« Synergy: One keyboard (and mouse) to rule them all | Main | Rails 1.1.5 Brouhaha »

August 05, 2006

Rails: Calling render() outside your Controllers

I found myself needing to render a .rxml template from my Model today (Ok, stop the MVC preach already...) anyways.. found a few deadends, but finally got down to use method_missing to see what's needed by ActionViewer::Base. Not sure if there's an easier way...

 

# 
# lib/render_anywhere.rb
#
# Render templates outside of a controller or view.
#
# Simply mixin this module to your existing class, for example:
#
# class MyTemplater < ActiveRecord::Base
# include RenderAnywhere
#
# And you can use render() method that works the same as ActionView::Base#render
#
# obj = MyTemplater.new
# obj.html = obj.render :file => '/shared/header'
#
#
module RenderAnywhere

class DummyController
def logger
RAILS_DEFAULT_LOGGER
end
def headers
{}
end
end

def render(options, assigns = {})
viewer = ActionView::Base.new(Rails::Configuration.new.view_path, assigns, DummyController.new)
viewer.render options
end

def template_exists?(path, assigns = {})
viewer = ActionView::Base.new(Rails::Configuration.new.view_path, assigns, DummyController.new)
viewer.pick_template_extension(path) rescue false
end
end

Hope this is helpful to someone 

TrackBack

TrackBack URL for this entry:
http://www.typepad.com/services/trackback/6a00e398212d6f883300e3982162c98833

Listed below are links to weblogs that reference Rails: Calling render() outside your Controllers:

Comments

Great, but... How to pass variables to the template?? I've tried with :locals=>{:somevar=>'value'} and doesn't works.


Thanks

Yea, I haven't figured that out yet. maybe when I need it - my problem that day was to render a rxml file with variables from elsewhere.

Sure would love to hear any solution. Can probably tweak DummyController, but I'm not very sure.

You can actually render a template with a one liner, .eg:


ActionView::Base.new(Rails::Configuration.new.view_path).render(:partial => 'foo/bar', :locals => {:foo => 'bar'})

@willc: much better! thanks :-)

This has come up often for me and I wanted a more elegant solution. So I put together ActsAsRenderer to give models a simple and elegant way to render output to strings or files.

Please see:
http://davetroy.blogspot.com/2008/02/actsasrenderer-brings-output-to-models.html

Setting instance variables for the templates is easy: just add the name and value to the ActionView instance's @assigns hash, like this:

av = ActionView::Base.new(Rails::Configuration.new.view_path)
av.assigns[:foo] = "bar"
av.render "some/template/here"

Thanks for sharing this. I've got it mostly working but need to use UrlHelpers.

In other words, I'd like to include things like this in my templates (bad example):

Suggestions on how to do this?

Thanks
Jeff

Er, looks like it stripped out the rhtml which is the following wrapped correctly:
link_to 'Edit', edit_user_path(@user)

You could use:

result = ERB.new(template_content).result(binding)

Olivier

Verify your Comment

Previewing your Comment

This is only a preview. Your comment has not yet been posted.

Working...
Your comment could not be posted. Error type:
Your comment has been posted. Post another comment

The letters and numbers you entered did not match the image. Please try again.

As a final step before posting your comment, enter the letters and numbers you see in the image below. This prevents automated programs from posting comments.

Having trouble reading this image? View an alternate.

Working...

Post a comment

Blog powered by TypePad