Subtemplating with ERB

This is actually somewhat tricky. Rails does a lot for you in this area.

Here's something to get you started:

  <%= ERB.new(IO.read('subtemplate.rhtml'), nil, nil, '_erbout2').result %>

What ERB does is to take your template and turn it into pure Ruby code that builds up a string using a variable name called (by default) '_erbout'. When you call result(), the ruby code is eval'd in the context of the binding passed (or TOPLEVEL_BINDING if no binding is passed).

To do a sub-template, you need to eval the sub-template and insert it's results mid-stream. But all the eval-ing happens at once (when you do the outermost template), so you need to use a different output variable name in your subtemplate, or your subtemplate will stomp on the output of your outer template. Hence the '_erbout2' parameter to new(). If the subtemplate called yet another subtemplate, you would need another variable name, and so forth, for each level of nesting.

I have the same problem. I am translating an old ASP-application (pre dot.net) that uses textual includes to implement DRY. When I try to use ERB for this I get scoping problems

* Variables or functions declared in the subtemplate I try to read with erb are not 'remembered' when returning to the main view (that did the erb call)

Note. if a variable was declared the first time in the main view it is possible to change the value of that variable in the subtemplate and that new value is 'remembered'.

I can't see how you can implement good DRY-solution in ruby/rails given the above problem but it should be possible since ruby/rails is a much newer/more modern framework than old asp.

Of course you can put the methods in an helper method but then you don't have access to the <% %> tags and you don't have access to variables declared in the view.

Very grateful for any help!

/Kristofer

Christo Karlson wrote:

I can't see how you can implement good DRY-solution in ruby/rails given the above problem but it should be possible since ruby/rails is a much newer/more modern framework than old asp.

Of course you can put the methods in an helper method but then you don't have access to the <% %> tags and you don't have access to variables declared in the view.

As is was using ERB without Rails i made the switch to a template engine called tenjin. There it's possible to have clean subtemplate resolution.

Can't be of any help regarding rails.

cheers kerthi

I would think partials would serve you (laying out vars populated in the appropriate controller).

Have you looked at those at all?

Yes I tested quite a bit with different renders and partials. What I remembered was that it couldn't asked the variables declared before the render-statement. i.e. when you start rendering the subtemplate all the variables from the main template are forgotten.

Of course one solution is to declare the variables with @varname in the controller but I am working with a automatic translator from asp and I would really need to have the code in the views for a start with a subtemplating system that works just like a text-include (like in asp with <--#include file)

Yikes. Good luck with that. :wink:

The only thing that comes to my mind is the :locals hash you can pass in a call to render :partial. But it'd probably be as much of a pain to figure out how to have your transliterator make those calls as it would be to have it put variable creation code in the controllers...