# Subtemplating with ERB

**URL:** <https://www.ruby-forum.com/t/subtemplating-with-erb/121510>\
**Category:** Rails\
**Created:** [November 28, 2007, 3:54pm UTC](https://www.ruby-forum.com/t/subtemplating-with-erb/121510 "2007-11-28T15:54:12Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![sealedsun](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e68b1a/32.png) [@sealedsun](https://www.ruby-forum.com/u/sealedsun)\
**Post date:** [November 28, 2007, 3:54pm UTC](https://www.ruby-forum.com/t/subtemplating-with-erb/121510/1 "2007-11-28T15:54:12Z")

</div>

Hey!

I’m using Ruby withour Rails, but i make use of the ERB-template  
functionality. So i think is a good place to post this one here.

I want to do subtemplating, is that possible?

E.g. I have a index.rhtml file.  
In this file i have html code combined with some ruby fragments and in  
addition i want to include subtemplates, how do i do that?:

# \<%= header %\>

\<% # include subtemplate.rhtml here! %\>

\</body

thx

---

<div class="post-metadata">

**Author:** ![sealedsun](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e68b1a/32.png) [@sealedsun](https://www.ruby-forum.com/u/sealedsun)\
**Post date:** [November 28, 2007, 4:13pm UTC](https://www.ruby-forum.com/t/subtemplating-with-erb/121510/2 "2007-11-28T16:13:26Z")

</div>

On Nov 28, 2007 9:54 AM, Christian K.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> addition i want to include subtemplates, how do i do that?:

In rails the concept you are looking for is a partial template. As  
usual there are conventions to follow.

Partials have file names starting with an underscore. So the filename  
would be \_subtemplate.rhtml rather than just subtemplate.rhtml.

Then:

\<%= render :partial =\> ‘subtemplate’ %\>

where you want to include it.

–  
Rick DeNatale

My blog on Ruby  
[http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)

---

<div class="post-metadata">

**Author:** ![sealedsun](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e68b1a/32.png) [@sealedsun](https://www.ruby-forum.com/u/sealedsun)\
**Post date:** [November 28, 2007, 4:24pm UTC](https://www.ruby-forum.com/t/subtemplating-with-erb/121510/3 "2007-11-28T16:24:37Z")

</div>

On Wed, Nov 28, 2007 at 10:13:01AM -0500, Rick DeNatale wrote:

> On Nov 28, 2007 9:54 AM, Christian K.  
> [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > Hey!
> > 
> > I’m using Ruby withour Rails, but i make use of the ERB-template  
> > functionality. So i think is a good place to post this one here.
> > 
> > I want to do subtemplating, is that possible?  
> > […]
> 
> where you want to include it.

Christian, you are better off asking this on the ruby-talk mailing list  
rather than on the Rails list, since you are much more likely to get  
help  
with a non-Rails use of ERB. You’re probably going to mostly get  
responses  
that talk about render :partial, as above, on this list.

> Rick DeNatale  
> –Greg

---

<div class="post-metadata">

**Author:** ![sealedsun](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e68b1a/32.png) [@sealedsun](https://www.ruby-forum.com/u/sealedsun)\
**Post date:** [November 28, 2007, 4:39pm UTC](https://www.ruby-forum.com/t/subtemplating-with-erb/121510/4 "2007-11-28T16:39:54Z")

</div>

On Nov 28, 2007 9:54 AM, Christian K.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> addition i want to include subtemplates, how do i do that?:
> 
> # \<%= header %\>
> 
> \<% # include subtemplate.rhtml here! %\>

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.

---

<div class="post-metadata">

**Author:** ![sealedsun](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e68b1a/32.png) [@sealedsun](https://www.ruby-forum.com/u/sealedsun)\
**Post date:** [November 29, 2007, 7:59am UTC](https://www.ruby-forum.com/t/subtemplating-with-erb/121510/5 "2007-11-29T07:59:23Z")

</div>

Bob S. wrote:

> Here’s something to get you started:
> 
> \<%= ERB.new(IO.read(‘subtemplate.rhtml’), nil, nil, ‘\_erbout2’).result  
> %\>

i created two templates:

toplevel\_template.rhtml:

# \<%= header %\>
\<%= ERB.new(IO.read('sublevel\_template.rhtml'), nil, nil, '\_erbout2').result %\>

sublevel\_template.rhtml:

## \<%= header2 %\>

in Ruby I execute this code to setup the values:

template = ERB.new(File.read(‘toplevel\_template.rhtml’))

# set vars

header = “Welcome”  
header2 = “Header”

# create page

page = template.result(binding())

But i get the error: undefined local variable or method `header2’ for  
main:Object

What is wrong here?

thx ck

---

<div class="post-metadata">

**Author:** ![sealedsun](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e68b1a/32.png) [@sealedsun](https://www.ruby-forum.com/u/sealedsun)\
**Post date:** [October 23, 2008, 12:10am UTC](https://www.ruby-forum.com/t/subtemplating-with-erb/121510/6 "2008-10-23T00:10:14Z")

</div>

I have the same problem.  
I am translating an old ASP-application (pre [dot.net](http://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

---

<div class="post-metadata">

**Author:** ![sealedsun](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e68b1a/32.png) [@sealedsun](https://www.ruby-forum.com/u/sealedsun)\
**Post date:** [October 23, 2008, 7:55am UTC](https://www.ruby-forum.com/t/subtemplating-with-erb/121510/7 "2008-10-23T07:55:58Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![sealedsun](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e68b1a/32.png) [@sealedsun](https://www.ruby-forum.com/u/sealedsun)\
**Post date:** [October 23, 2008, 10:27pm UTC](https://www.ruby-forum.com/t/subtemplating-with-erb/121510/8 "2008-10-23T22:27:56Z")

</div>

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)

---

<div class="post-metadata">

**Author:** ![sealedsun](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e68b1a/32.png) [@sealedsun](https://www.ruby-forum.com/u/sealedsun)\
**Post date:** [October 23, 2008, 11:03pm UTC](https://www.ruby-forum.com/t/subtemplating-with-erb/121510/9 "2008-10-23T23:03:45Z")

</div>

Yikes. Good luck with that. 😉

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…

---

<div class="post-metadata">

**Author:** ![sealedsun](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e68b1a/32.png) [@sealedsun](https://www.ruby-forum.com/u/sealedsun)\
**Post date:** [October 23, 2008, 5:30pm UTC](https://www.ruby-forum.com/t/subtemplating-with-erb/121510/10 "2008-10-23T17:30:24Z")

</div>

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

Have you looked at those at all?
