diff --git a/lib/redmine/hook.rb b/lib/redmine/hook.rb index 83c9816b2..c8f483949 100644 --- a/lib/redmine/hook.rb +++ b/lib/redmine/hook.rb @@ -107,7 +107,13 @@ module Redmine # def self.render_on(hook, options={}) define_method hook do |context| - context[:controller].send(:render_to_string, {:locals => context}.merge(options)) + if context[:hook_caller].respond_to?(:render) + context[:hook_caller].send(:render, {:locals => context}.merge(options)) + elsif context[:controller].is_a?(ActionController::Base) + context[:controller].send(:render_to_string, {:locals => context}.merge(options)) + else + raise "Cannot render #{self.name} hook from #{context[:hook_caller].class.name}" + end end end @@ -138,14 +144,15 @@ module Redmine # * project => current project # * request => Request instance # * controller => current Controller instance + # * hook_caller => object that called the hook # module Helper def call_hook(hook, context={}) if is_a?(ActionController::Base) - default_context = {:controller => self, :project => @project, :request => request} + default_context = {:controller => self, :project => @project, :request => request, :hook_caller => self} Redmine::Hook.call_hook(hook, default_context.merge(context)) else - default_context = { :project => @project } + default_context = { :project => @project, :hook_caller => self } default_context[:controller] = controller if respond_to?(:controller) default_context[:request] = request if respond_to?(:request) Redmine::Hook.call_hook(hook, default_context.merge(context)).join(' ').html_safe diff --git a/test/integration/lib/redmine/hook_test.rb b/test/integration/lib/redmine/hook_test.rb index bbea0e643..790ae6a52 100644 --- a/test/integration/lib/redmine/hook_test.rb +++ b/test/integration/lib/redmine/hook_test.rb @@ -35,6 +35,17 @@ class MenuManagerTest < ActionController::IntegrationTest end end + class ContentForInsideHook < Redmine::Hook::ViewListener + render_on :view_welcome_index_left, :inline => <<-VIEW +<% content_for :header_tags do %> + <%= javascript_include_tag 'test_plugin.js', :plugin => 'test_plugin' %> + <%= stylesheet_link_tag 'test_plugin.css', :plugin => 'test_plugin' %> +<% end %> + +
ContentForInsideHook content
+VIEW + end + def setup Redmine::Hook.clear_listeners end @@ -64,4 +75,16 @@ class MenuManagerTest < ActionController::IntegrationTest assert_select 'div#main' assert_select 'div#main.nosidebar', 0 end + + def test_hook_with_content_for_should_append_content + Redmine::Hook.add_listener(ContentForInsideHook) + + get '/' + assert_response :success + assert_select 'p', :text => 'ContentForInsideHook content' + assert_select 'head' do + assert_select 'script[src=/plugin_assets/test_plugin/javascripts/test_plugin.js]' + assert_select 'link[href=/plugin_assets/test_plugin/stylesheets/test_plugin.css]' + end + end end diff --git a/test/unit/lib/redmine/hook_test.rb b/test/unit/lib/redmine/hook_test.rb index 225d49bda..4d42aa890 100644 --- a/test/unit/lib/redmine/hook_test.rb +++ b/test/unit/lib/redmine/hook_test.rb @@ -89,7 +89,7 @@ class Redmine::Hook::ManagerTest < ActionView::TestCase def test_call_hook_with_context @hook_module.add_listener(TestHook3) - assert_equal ['Context keys: bar, controller, foo, project, request.'], + assert_equal ['Context keys: bar, controller, foo, hook_caller, project, request.'], hook_helper.call_hook(:view_layouts_base_html_head, :foo => 1, :bar => 'a') end