Conditional render_on?

Added by Daniel Vandersluis over 8 years ago

Is there a way to call render_on (for a view hook) conditionally? Before, I was just using a hook method, in which I only showed the view code if the module is enabled for the project and if the user has view permission. Now that I'm using render_on and a partial, I can't figure out how to make these checks from within the hook.

Any help would be appreciated, thanks! :)

Replies (5)

RE: Conditional render_on? - Added by Eric Davis over 8 years ago

You can't yet. If you want to open a feature request or submit a patch, an :if option might work

class MyHook < Redmine::Hook::ViewListener
  render_on :view_issues_show_details_bottom, :partial => "show_more_data", :if => Proc.new {|context| User.current.admin? && context[:project].module_enabled?('foo_module')}
end

It will be a while before I can apply it, I've been busy breaking (and hopefully fixing) the plugin API recently and I'd like to let the dust settle a bit. :)

Eric

RE: Conditional render_on? - Added by Daniel Vandersluis over 8 years ago

Hm, okay. I was hoping there'd be a way to do an :if, but that's alright. Seems like render_on is pretty new, anyways, and I guess it does work for now having the logic in the partial.

I'll try to play around with render_on and see if I can come up with a patch, but it might be beyond my capabilities at the moment. Any hints to get started would be appreciated :)

RE: Conditional render_on? - Added by Thomas Löber over 8 years ago

This should work (in class ViewListener):

      def self.render_on(hook, options={})
        define_method hook do |context|
          if !options.include?(:if) || evaluate_if_option(options[:if], context)
            context[:controller].send(:render_to_string, {:locals => context}.merge(options))
          end
        end
      end

      private

      def evaluate_if_option(if_option, context)
        case if_option
        when Symbol
          send(if_option, context)
        when Method, Proc
          if_option.call(context)
        end        
      end
    end

You can even define this in your ViewListener hook class:

private
def is_admin?(context)
  User.current.admin? && context[:project].module_enabled?('foo_module')
end

and call render_on like this:

render_on :view_issues_show_details_bottom, :partial => "show_more_data", :if => :is_admin?

RE: Conditional render_on? - Added by Daniel Vandersluis over 8 years ago

Thanks, that worked perfectly :)

RE: Conditional render_on? - Added by Nicolas Rodriguez over 4 years ago

Hi there!

I did a Redmine module whith this snippet, but every time I do a change in code in dev mode, I get this error :

ActionView::Template::Error (undefined method `call_hook' for #<#<Class:0x00000005668528>:0x00000005683b20>):
    11: <%= stylesheet_link_tag 'rtl', :media => 'all' if l(:direction) == 'rtl' %>
    12: <%= javascript_heads %>
    13: <%= heads_for_theme %>
    14: <%= call_hook :view_layouts_base_html_head %>
    15: <!-- page specific tags -->
    16: <%= yield :header_tags -%>
    17: </head>
  app/views/layouts/admin.html.erb:8:in `_app_views_layouts_admin_html_erb___1667192755468428064_48808960'

I tried to put 'unloadable' a the top of the class, but it does not work.

How can I enable autoreload for this class?

Thank you!

(1-5/5)