Newbie templating question: how to combine multiple files

F

Frank Reiff

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
 
J

John Joyce

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.
 
P

Phillip Gawlowski

John said:
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.
 
J

Jano Svitok

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

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
 
F

Frank Reiff

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.
 
F

Frank Reiff

Jano said:
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>
 
J

John Joyce

Yeah, SQLite is a good choice for speed especially, but it isn't =20
nearly as well documented as MySQL or PostgreSQL so if you go with a =20
database, start with something well-documented and with a good book =20
so you don't get lost.
For small site (like 10 pages or less) that doesn't change often, =20
just avoid a database for the site as a whole. If you need a news =20
page that gets updated regularly, then you might want more, but an =20
easy solution is to use a blog for news and customize the appearance. =20=

Lots of Rubyists and Rails people use WordPress because it works so =20
well and is well documented and proven as a solution. Never mind that =20=

it is PHP driven, that's not a bad thing. If you're planning to use =20
Ruby for web sites, it might be good to learn about PHP too, you can =20
see a lot of cool ideas there and good functionality. You can always =20
recreate it in Ruby!
A good tool for this kind of comparison are the OReilly books PHP =20
Cookbook and Ruby Cookbook. They focus on little code solutions to do =20=

specific things. (though I must say the Ruby Cookbook is slightly =20
better because it goes into greater detail of explaining what and =20
why). The Ruby Cookbook is also good for building muscles, because =20
it's not lightweight.
If your muscles get too big, you'll have to switch to Python, because =20=

many Python books are just very thick and heavy.
(=E7=AC=91)
And this is where CSS comes in: the division of "Website logic" and =20=
 
P

Phillip Gawlowski

John said:
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.
 
J

Jano Svitok

Jano said:
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>

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
 
F

Frank Reiff

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top