Michael Schuerig
2010-Jul-04 14:07 UTC
Rendering a different format in the implementation of a renderer
Yehuda has a nice article on implementing a custom renderer for PDF at http://www.engineyard.com/blog/2010/render-options-in-rails-3/ I''ve tried to follow the example and I''m not sure I see how to get it to work. If I understand things correctly, the format(s) usable in this render call respond_with(@resource) do |format| format.xyz { render :xyz => ... } end are set to xyz. Thus templates (for actions, partials, and layouts) are looked up based on only this format, e.g. show.xyz.erb. This is the correct behavior, of course, but there are legitimate reasons for wanting to override it. For instance, implementing one renderer in terms of another. In my particular case, I''m trying to get HTML rendered in order to convert it to PDF. As I can see no other clean way, I wish ActionView::LookupContext had a method #with_format(format) { ... } for overriding the format for the duration of the block. Such a renderer could then look like this ActionController.add_renderer(:xyz) do |template, options| lookup_context.with_format(:html) do html = render(template, options) convert_html_to_xyz(html) end end Or, even easier, :format could be an option to #render. Michael -- Michael Schuerig mailto:michael@schuerig.de http://www.schuerig.de/michael/ -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
Yehuda Katz
2010-Jul-04 17:44 UTC
Re: Rendering a different format in the implementation of a renderer
You can do something like this in Rails 3: render :partial => "foo.html" if you''re in an XML template et al. Yehuda Katz Architect | Engine Yard (ph) 718.877.1325 On Sun, Jul 4, 2010 at 7:07 AM, Michael Schuerig <michael@schuerig.de>wrote:> > Yehuda has a nice article on implementing a custom renderer for PDF at > > http://www.engineyard.com/blog/2010/render-options-in-rails-3/ > > I''ve tried to follow the example and I''m not sure I see how to get it to > work. If I understand things correctly, the format(s) usable in this > render call > > respond_with(@resource) do |format| > format.xyz { render :xyz => ... } > end > > are set to xyz. Thus templates (for actions, partials, and layouts) are > looked up based on only this format, e.g. show.xyz.erb. > > This is the correct behavior, of course, but there are legitimate > reasons for wanting to override it. For instance, implementing one > renderer in terms of another. In my particular case, I''m trying to get > HTML rendered in order to convert it to PDF. > > As I can see no other clean way, I wish ActionView::LookupContext had a > method #with_format(format) { ... } for overriding the format for the > duration of the block. Such a renderer could then look like this > > ActionController.add_renderer(:xyz) do |template, options| > lookup_context.with_format(:html) do > html = render(template, options) > convert_html_to_xyz(html) > end > end > > Or, even easier, :format could be an option to #render. > > Michael > > -- > Michael Schuerig > mailto:michael@schuerig.de > http://www.schuerig.de/michael/ > > -- > You received this message because you are subscribed to the Google Groups > "Ruby on Rails: Core" group. > To post to this group, send email to rubyonrails-core@googlegroups.com. > To unsubscribe from this group, send email to > rubyonrails-core+unsubscribe@googlegroups.com<rubyonrails-core%2Bunsubscribe@googlegroups.com> > . > For more options, visit this group at > http://groups.google.com/group/rubyonrails-core?hl=en. > >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
Michael Schuerig
2010-Jul-04 18:18 UTC
Re: Rendering a different format in the implementation of a renderer
On Sunday 04 July 2010, Yehuda Katz wrote:> You can do something like this in Rails 3: > > render :partial => "foo.html" if you''re in an XML template et al.Yes, I know, but that doesn''t help in this particular case. I''m not just rendering a partial, I want the whole view. Now, render :template => "foo.html" does work for the template itself, but that doesn''t change that render (LookupContext, really) still uses the original, "enclosing" format, to look for a layout template. Say I have respond_with(@resource) do |format| format.pdf { render :pdf => ''show, :layout => print } end and the renderer does something like this ActionController.add_renderer :pdf do |template, options| filename = options.delete(:filename) options = options.merge(:template => "#{template}.html") html = render_to_string(options) send_data(convert_html_to_pdf(html)) end Here render_to_string finds and uses the HTML template. But as there is no print.pdf.erb, it doesn''t wrap a layout around the content. Now, then I just rename print.html.erb to print.pdf.erb. That does work, but only as long as I don''t need to include any further partials in the layout. For those partials, LookupContext enforces that they must have format PDF. As no such partials exist, and as I don''t want to define them, things blow up because of missing templates. As I said, I think it would be useful to have a way to force the rendered format. However, I don''t yet understand the architecture well enough to be entirely sure that this is a good idea. Michael -- Michael Schuerig mailto:michael@schuerig.de http://www.schuerig.de/michael/ -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.