3

I've been trying to create a custom renderer based on this Yehuda Katz's blog post.

It works if I call render :my_custom_renderer => "index", but it doesn't work with default respond_with or format.my_custom_renderer

I created a simple example, .

From a blank app, add the following lines:

In config/mime_types.rb:

Mime::Type.register_alias 'text/html', :my_custom_renderer

In config/my_custom_renderer.rb:

require "action_controller/metal/renderers"
ActionController.add_renderer :my_custom_renderer do |template, options|
  self.mime_type ||= Mime::HTML
  self.response_body = render_to_string(template).sub(/^/, 
                                                '\1<h1>Rendering Injection</h1>')
end

In app/views/custom_renderer_test/index.my_custom_renderer.erb:

<h1>A message "Rendering Injection" should appear above</h1>

In app/controllers/custom_renderer_test_controller.rb:

class CustomRenderingTestController < ApplicationController
  def index
    respond_to do |format|
      # does not go through my custom renderer!
      format.my_custom_renderer 
      # although it works if I explicitly do:
      # format.my_custom_renderer { render :my_custom_renderer => 'index' }
    end
  end
end

And, finally, in config/routes.rb:

root :to => "custom_rendering_test#index"

Starting up a server and going to the root page should display the message from my_custom_renderer, but it does not. I've tried debugging Rails source step by step, but looks like I don't understand rendering architecture well-enough.

Can someone please give me a hint on what the problem is?

glebm
  • 20,282
  • 8
  • 51
  • 67
  • You need to pass the format variable, so you'd need to set up the route to pass it. – Jakub Hampl Mar 12 '11 at 18:18
  • Rails 3 passes it for all the routes automatically. Still, tried adding it -- does not work. (I did: `match "/test(.:format)" => "custom_rendering_test#index"` and `root :to => redirect("/test.my_custom_renderer")`) – glebm Mar 12 '11 at 18:21
  • Got it to work (updated the question), but not in a nice way – glebm Mar 12 '11 at 18:43

1 Answers1

2

What might help is to create a responder (and use the newer respond_with) with the explicit method:

class ActionController::Responder
  def to_my_custom_renderer
    controller.render :my_custom_renderer => controller.action_name
  end
end
Jakub Hampl
  • 39,863
  • 10
  • 77
  • 106