Newbie templating question: how to combine multiple files

Hi,

I use ERB for some very basic HTML templating (no Rails!). In essence, I
have normal HTML pages produced by Adobe GoLive (the WORST HTML editor
ever) with a couple of simple tags along the lines of <%=
@myProduct.price %>.

Now, I'm planning to replace GoLive's templating mechanism with ruby.

Ideally, the solution would look something like this:

* each file is a simple HTML file that remains editable in a normal HTML
editor, e.g.

<html>
<body
  <p>Hello World</p>
</body>
<html>

* the template itself is an HTML file that remains editable in a normal
HTML editor, something along these lines:

<html>
<header><%= headertag() %></header>
<body
  <div id="content">
    <%= content() %>
  </div>
  <div id="navigataion">
    <%= navigation() %>
  </div>
</body>
<html>

Looking at the documentation for the ERB class, I can't find a simple
way of including another template inside a template file. I guess I
could simply do a require, but that will simply copy the entire contents
of the file as ruby code. How do you usually subdivide your templates
into multiple files (e.g. header, variable content, footer, etc.) using
ERB?

Are there any better templating solutions available that could deal with
combining multiple HTML pages into a single one?

Any help would be appreciated.

Best regards,

Frank

···

--
Posted via http://www.ruby-forum.com/.

Looking at the documentation for the ERB class, I can't find a simple
way of including another template inside a template file. I guess I
could simply do a require, but that will simply copy the entire contents
of the file as ruby code. How do you usually subdivide your templates
into multiple files (e.g. header, variable content, footer, etc.) using
ERB?

Frank, this is exactly how templates are done.
It's kind of breaking a page into separate files for commonly repeated elements, making them easier to change.
Regardless of the language you use to do it, it's the same;
you make a skeleton like this (this is pseudo code)

general, this is all or almost every page on the site:
1.variables defining body id and page title, etc... to be substituted into all included files!
2.include (header)
3.content actually in here or include it from a file
4.include (footer)

header:
doctype and head section,
up to opening tag of body element.
usually include(navigation list) at the end of this file

content:
this one is obvious.

footer:
perhaps include(navigation list) again and style it differently here
closing body element tag
closing html element tag
this is also the section to place javascript usually (makes pages seem like they load faster, browser reads javascript after rather than before content loads. depends on what the js does, but especially the place for site analysis scripts)

navigation list:
this is your main list of site navigation links.

That's it basically. It can be more complex and sophisticated, like Rails or WordPress.
For simple sites, templates are an easier way to maintain much of it.
For bigger sites with more complex systems behind them, you find that templates are still there!
So, one web page should consist of at least 4 files, or more. More means more complication of logic.
The only parts that would be different for any page are the content.
As you can start to see for bigger sites, content and title and link variables start to be obvious targets for a database, if the site is big enough. Don't bother with a database unless you know you have a lot of stuff for a site.
Using a format like this you can later transfer it to a more complex system pretty easily if you need to.

Hi Frank,

have a look at rails source how it is done. It's quite easy. The
following code I almost copied from there (I do template caching in a
member attribute in addition).

I include this code in the object that
renders the templates, but with a little modifications, you can use it from
top level scope as well (e.g. after you get rid of @'s)

        def render(template, local_assigns = {})
                b = evaluate_locals(local_assigns)
                rhtml = @templates[template]
                if rhtml.nil?
                        template_filename = File.join(@template_dir, template)
                        rhtml = ERB.new(File.read(template_filename),
nil, "%<>")
                        @templates[template] = rhtml
                end
                rhtml.result(b)
        end

        def evaluate_locals(local_assigns = {})
                b = binding
                local_assigns.each { |key, value| eval "#{key} =
local_assigns[\"#{key}\"]", b }
                b
        end

HTH,

Jano

···

On 3/23/07, Frank Reiff <reiff@publicspace.net> wrote:

Hi,

I use ERB for some very basic HTML templating (no Rails!). In essence, I
have normal HTML pages produced by Adobe GoLive (the WORST HTML editor
ever) with a couple of simple tags along the lines of <%=
@myProduct.price %>.

Now, I'm planning to replace GoLive's templating mechanism with ruby.

Ideally, the solution would look something like this:

* each file is a simple HTML file that remains editable in a normal HTML
editor, e.g.

<html>
<body
  <p>Hello World</p>
</body>
<html>

* the template itself is an HTML file that remains editable in a normal
HTML editor, something along these lines:

<html>
<header><%= headertag() %></header>
<body
  <div id="content">
    <%= content() %>
  </div>
  <div id="navigataion">
    <%= navigation() %>
  </div>
</body>
<html>

Looking at the documentation for the ERB class, I can't find a simple
way of including another template inside a template file. I guess I
could simply do a require, but that will simply copy the entire contents
of the file as ruby code. How do you usually subdivide your templates
into multiple files (e.g. header, variable content, footer, etc.) using
ERB?

Are there any better templating solutions available that could deal with
combining multiple HTML pages into a single one?

Any help would be appreciated.

Best regards,

Frank

Just some clarifications about my question:

I'm a Ruby newbie, but have quite a lot of Java/C/C++/Objective-C
experience, so it's not the templating concept that I'm unsure about but
the HOW of using templates in Ruby.

I've written a ruby fcgi website dispatcher that performs all kinds of
extra "behind the scenes" processing, but at the moment I only use ERB
in a token fashion. Combining multiple legal HTML files into a single
page is where I could do with some pointers. As far as I can see ERB
can't do this..

I have come across some references to Nitro, which does seem to have a
pretty decent templating engine, but I don't want to pull a whole MVC
framework (not to mention Og).. I'm basically looking for a standalone
templating solution.

···

--
Posted via http://www.ruby-forum.com/.

Thanks for all the suggestions.

In the end, I've just written my own templating engine, which may not be
the world's most powerful, but does exactly what I want it do..

Best regards,

Frank

···

--
Posted via http://www.ruby-forum.com/.

John Joyce wrote:

That's it basically. It can be more complex and sophisticated, like Rails or WordPress.
For simple sites, templates are an easier way to maintain much of it.
For bigger sites with more complex systems behind them, you find that templates are still there!

And this is where CSS comes in: the division of "Website logic" and Website layout. You can use that to great effect, especially with a server-side scripting language.

At least, in theory, but I have no experience on how to do this kind of stuff.

The only parts that would be different for any page are the content.
As you can start to see for bigger sites, content and title and link variables start to be obvious targets for a database, if the site is big enough. Don't bother with a database unless you know you have a lot of stuff for a site.

Or use a small one, like SQLite, which has a very nice Ruby interface (either via sqlite3-ruby, or ruby-dbi). Very good to practice with databases (as it is very, very small), at least, and supposedly used for websites, too, with medium traffic (around 1M per day, AFAIK).

···

--
Phillip "CynicalRyan" Gawlowski

Rule of Open-Source Programming #15:

If you like it, let the author know. If you hate it, let the author
know why.

Jano Svitok wrote:

HTML editor, something along these lines:
</body>
combining multiple HTML pages into a single one?

Any help would be appreciated.

Best regards,

Frank

Hi Frank,

have a look at rails source how it is done. It's quite easy. The
following code I almost copied from there (I do template caching in a
member attribute in addition).

I include this code in the object that
renders the templates, but with a little modifications, you can use it
from
top level scope as well (e.g. after you get rid of @'s)

        def render(template, local_assigns = {})
                b = evaluate_locals(local_assigns)
                rhtml = @templates[template]
                if rhtml.nil?
                        template_filename = File.join(@template_dir,
template)
                        rhtml = ERB.new(File.read(template_filename),
nil, "%<>")
                        @templates[template] = rhtml
                end
                rhtml.result(b)
        end

        def evaluate_locals(local_assigns = {})
                b = binding
                local_assigns.each { |key, value| eval "#{key} =
local_assigns[\"#{key}\"]", b }
                b
        end

Thanks. One question though. The File.join presumably simply copies the
contents of the linked file, so won't this insert the enclosing <html>
tag into the output?

<html>
<body>
  <%=render("header.html"%>
  <p>Hello World </p>
</body>
</html>

becomes

<html>
<body>
  <html><body><h1>My Header</h1></body></html>
  <p>Hello World </p>
</body>
</html>

···

On 3/23/07, Frank Reiff <reiff@publicspace.net> wrote:

--
Posted via http://www.ruby-forum.com/\.

Yeah, SQLite is a good choice for speed especially, but it isn't nearly as well documented as MySQL or PostgreSQL so if you go with a database, start with something well-documented and with a good book so you don't get lost.
For small site (like 10 pages or less) that doesn't change often, just avoid a database for the site as a whole. If you need a news page that gets updated regularly, then you might want more, but an easy solution is to use a blog for news and customize the appearance. Lots of Rubyists and Rails people use WordPress because it works so well and is well documented and proven as a solution. Never mind that it is PHP driven, that's not a bad thing. If you're planning to use Ruby for web sites, it might be good to learn about PHP too, you can see a lot of cool ideas there and good functionality. You can always recreate it in Ruby!
A good tool for this kind of comparison are the OReilly books PHP Cookbook and Ruby Cookbook. They focus on little code solutions to do specific things. (though I must say the Ruby Cookbook is slightly better because it goes into greater detail of explaining what and why). The Ruby Cookbook is also good for building muscles, because it's not lightweight.
If your muscles get too big, you'll have to switch to Python, because many Python books are just very thick and heavy.
(笑)

···

On Mar 23, 2007, at 8:38 PM, Phillip Gawlowski wrote:

John Joyce wrote:

That's it basically. It can be more complex and sophisticated, like Rails or WordPress.
For simple sites, templates are an easier way to maintain much of it.
For bigger sites with more complex systems behind them, you find that templates are still there!

And this is where CSS comes in: the division of "Website logic" and Website layout. You can use that to great effect, especially with a server-side scripting language.

At least, in theory, but I have no experience on how to do this kind of stuff.

The only parts that would be different for any page are the content.
As you can start to see for bigger sites, content and title and link variables start to be obvious targets for a database, if the site is big enough. Don't bother with a database unless you know you have a lot of stuff for a site.

Or use a small one, like SQLite, which has a very nice Ruby interface (either via sqlite3-ruby, or ruby-dbi). Very good to practice with databases (as it is very, very small), at least, and supposedly used for websites, too, with medium traffic (around 1M per day, AFAIK).

--
Phillip "CynicalRyan" Gawlowski

Rule of Open-Source Programming #15:

If you like it, let the author know. If you hate it, let the author
know why.

File.join is used for joining pathnames. See the docs.

The output depends on the content of the included template. If there's
<html> then it'll be in the output and vice versa.

so if header.html contains:
<html><body><h1>My Header</h1></body></html>

then you'll have the output you wrote, but if there's only:

<h1>My Header</h1>

then you'll probably get what you want.

Jano

···

On 3/23/07, Frank Reiff <reiff@publicspace.net> wrote:

Jano Svitok wrote:
> On 3/23/07, Frank Reiff <reiff@publicspace.net> wrote:
>>
>> HTML editor, something along these lines:
>> </body>
>> combining multiple HTML pages into a single one?
>>
>> Any help would be appreciated.
>>
>> Best regards,
>>
>> Frank
>>
>
> Hi Frank,
>
> have a look at rails source how it is done. It's quite easy. The
> following code I almost copied from there (I do template caching in a
> member attribute in addition).
>
> I include this code in the object that
> renders the templates, but with a little modifications, you can use it
> from
> top level scope as well (e.g. after you get rid of @'s)
>
> def render(template, local_assigns = {})
> b = evaluate_locals(local_assigns)
> rhtml = @templates[template]
> if rhtml.nil?
> template_filename = File.join(@template_dir,
> template)
> rhtml = ERB.new(File.read(template_filename),
> nil, "%<>")
> @templates[template] = rhtml
> end
> rhtml.result(b)
> end
>
> def evaluate_locals(local_assigns = {})
> b = binding
> local_assigns.each { |key, value| eval "#{key} =
> local_assigns[\"#{key}\"]", b }
> b
> end

Thanks. One question though. The File.join presumably simply copies the
contents of the linked file, so won't this insert the enclosing <html>
tag into the output?

<html>
<body>
  <%=render("header.html"%>
  <p>Hello World </p>
</body>
</html>

becomes

<html>
<body>
  <html><body><h1>My Header</h1></body></html>
  <p>Hello World </p>
</body>
</html>

John Joyce wrote:

Yeah, SQLite is a good choice for speed especially, but it isn't nearly as well documented as MySQL or PostgreSQL so if you go with a database, start with something well-documented and with a good book so you don't get lost.

Well, I disagree. I found that documentation of SQLite3 better, than that of MySQL. But then, those are very different beasts, with different target audiences.

A book that introduces SQL in general, together with SQLite3 is a good introduction to relational databases. MySQL is nice to find out what permission and ACL is all about, and you can move to Oracle XE (a free version of the Oracle datbase), if you want to mess around with the big players.

For small site (like 10 pages or less) that doesn't change often, just avoid a database for the site as a whole. If you need a news page that gets updated regularly, then you might want more, but an easy solution is to use a blog for news and customize the appearance.

Well, a Blog is, essentially, a "dumbed down" (or rather: focusing on one aspect) CMS, and a good way to present news-like stuff.
But that can be done equally well with, say, and HTML editor with FTP support, where you can upload your local files (making it a Client-Server-CMS, instead of a pure webdriven CMS, like Drupal or Joomla).

Lots of Rubyists and Rails people use WordPress because it works so well and is well documented and proven as a solution. Never mind that it is PHP driven, that's not a bad thing. If you're planning to use Ruby for web sites, it might be good to learn about PHP too, you can see a lot of cool ideas there and good functionality. You can always recreate it in Ruby!

Well, WordPress is riddled with security problems, which come, in part, from PHP. (http://www.securityfocus.com/columnists/432\)

But yeah, there are a lot of well-written, and very usable PHP aplications (Joomla, TikiWiki, to name just two). And a ready supply for ideas, too.

A good tool for this kind of comparison are the OReilly books PHP Cookbook and Ruby Cookbook. They focus on little code solutions to do specific things. (though I must say the Ruby Cookbook is slightly better because it goes into greater detail of explaining what and why). The Ruby Cookbook is also good for building muscles, because it's not lightweight.
If your muscles get too big, you'll have to switch to Python, because many Python books are just very thick and heavy.

Well, quantity doesn't relate to quality. And the Pickaxe isn't lightweight, either.

But yes, it is important to not focus just on one language, as other languages, and their usage, can be very enlightening. Although I'm horrified by the look of PHP code, compared to Ruby.

I'd say, that Rubyists especially should look beyond just Ruby. (I'm planning to do that, once I can count myself as a Rubyist. My skills aren't very developed yet).

···

--
Phillip "CynicalRyan" Gawlowski

Rule of Open-Source Programming #4:

If you don't work on your project, chances are that no one will.