An alternative HTML generation syntax

I’m using Ruby to output HTML a lot these days. I know of these
methods:

  1. Use CGI::Html4. Problem: Must use ‘+’ all the time to join things.
    If I forget a ‘+’, everything in the block before the ‘+’ will get
    silently ignored since only the return value matters.

  2. Manually using puts or print statements. I get tired of having to
    type ‘puts’ all the time.

  3. Use eruby. Problem: Can’t seem to use this inside methods.

I’m trying to come up with another method of HTML generation that
minimizes typing and is readable.

Here’s an example. Instead of this piece of code:

puts "

"
puts “NEW!” if flag == 'new’
puts “UPDATED!” if flag == 'updated’
puts "
"
if numparts > 1
puts “Parts:”
(1…numparts).each do |i|
puts %Q{ [#{i}]}
end
end
puts “by #{author.display}” if author
puts “

It would be this:

HTML.new { p {
t ‘NEW!’ if flag == 'new’
t ‘UPDATED!’ if flag == 'updated’
br
if numparts > 1
t ‘Parts:’
(1…numparts).each do |i|
a(:href => “#{i}.asp”) { “[#{i}]” }
end
end
} }

The HTML class would be something like this:

class HTML
def initialize(&block)
@buff = ''
self.instance_eval &block
puts @buff
end

def p
    @buff += "<P>#{yield || @buff}</P>"
end
# define a, h1, h2, etc. and all the other HTML tags similarly

end

Whenever an HTML function (like “p” or “a”) is called, it will
generate some HTML code and tack it onto a buffer. Finally at the end,
the contents of the buffer are returned.

Any thoughts on this? Do you like the interface to my HTML class (can
it be made any easier)? Are there any other HTML-generation-with-Ruby
methods that I missed?

It would be this:

HTML.new { p {
t ‘NEW!’ if flag == ‘new’
t ‘UPDATED!’ if flag == ‘updated’
br
if numparts > 1
t ‘Parts:’
(1…numparts).each do |i|
a(:href => “#{i}.asp”) { “[#{i}]” }
end
end
} }

The HTML class would be something like this:

class HTML
def initialize(&block)
@buff = ‘’
self.instance_eval &block

Why not yield?

    puts @buff
end

def p
    @buff += "<P>#{yield || @buff}</P>"
end
# define a, h1, h2, etc. and all the other HTML tags similarly

end

This should certainly work. I’d suggest using method_missing and have a
class local configuration which says elements html allows and which
attributes are needed. Sth. like i micro dtd:

class HTML
@@dtd = { :html => {},
:head => {},
:title => {},
:body => {:bgcolor, :link, :vlink, :alink}
}

def methods_missing(symbol, *attrs)
raise “Invalid element: #{symbol}” unless @@dtd.has_key? symbol
@buff << “<#{symbol}>#{yield || @buff}</#{symbol}>”
end
end

You can go even further and use a DTD parser to decouple this nifty tool
from HTML. Make it a Provider of a SAX Stream, e.g.

-billy.

···

Am Sam, 2002-11-09 um 09.47 schrieb Philip Mak:

Meisterbohne Söflinger Straße 100 Tel: +49-731-399 499-0
eLösungen 89077 Ulm Fax: +49-731-399 499-9

I don’t like these “tags are methods”, um, methods. Frankly, they’re
almost as bad as using puts() as far as seperating markup from content
generation.

I’ve written a lot of PHP template engines, and I’ve had some nice ideas
which PHP made quite difficult to implement; Ruby’s flexibility could
make for some interesting engines, IMO.

Concider something like:

t = FreakyTemplate.new(‘foo.tpl’)
t.head(:title => “Title”, :author => “Me”)
t.body(:heading => “Article List”)

articles.each do |a|
t.body.article(a)
end

print t

Using the template:

<?xml version="1.0" encoding="utf-8" ?> {block:head} {title} {/block}

{block:body}

{heading}

{block:article(a)}

{a.title}

By {a.author}

{a.body}

{/block}
{/block}

This closely mirrors an (unreleased) isotemplate engine I wrote in PHP.

···

I’m using Ruby to output HTML a lot these days. I know of these
methods:

  1. Use CGI::Html4. Problem: Must use ‘+’ all the time to join things.
    If I forget a ‘+’, everything in the block before the ‘+’ will get
    silently ignored since only the return value matters.


Thomas ‘Freaky’ Hurst - freaky@aagh.net - http://www.aagh.net/

Woman: “Is Yoo-Hoo hyphenated?”
Yogi Berra: “No, ma’am, its not even carbonated.”

I am a big fan of Amrita for HTML-generation.

Not only does it have some amazing templating capabilities, but it also has
methods like Amrita::e (for creation of new tags) and Amrita::a (for runtime
editing of template tags) that make life a lot easier.

I’m using amrita for a number of projects at the moment, including my personal
website and work for a client, and find it to be an extremely flexible
solution.

···

On Saturday 09 November 2002 03:47 am, Philip Mak wrote:

Are there any other HTML-generation-with-Ruby
methods that I missed?


Bruce Williams
bruce@codedbliss.com

I was really wowed by Narf at RubyConf. It’s got built in templating,
reasonable looking HTML generation, CGI bits, and (best of all) it’s got
test::Unit hooks built in allowing you to easily test your web application
from the command line.

-pate

···

On Sun, 10 Nov 2002, Bruce Williams wrote:

On Saturday 09 November 2002 03:47 am, Philip Mak wrote:

Are there any other HTML-generation-with-Ruby
methods that I missed?

I am a big fan of Amrita for HTML-generation.

Not only does it have some amazing templating capabilities, but it also has
methods like Amrita::e (for creation of new tags) and Amrita::a (for runtime
editing of template tags) that make life a lot easier.

I’m using amrita for a number of projects at the moment, including my personal
website and work for a client, and find it to be an extremely flexible
solution.


Bruce Williams
bruce@codedbliss.com

Actually, NARF is one of the libraries on my list to check out. But I’m not
sure I’d switch to NARF templating; I’m quite fond of Amrita’s pure xhtml
templating capability and the Amrita::ExpandByMember mixin. That said, I
certainly look forward to using NARFs CGI bits.

···

On Saturday 09 November 2002 12:50 pm, Pat Eyler wrote:

I was really wowed by Narf at RubyConf. It’s got built in templating,
reasonable looking HTML generation, CGI bits, and (best of all) it’s got
test::Unit hooks built in allowing you to easily test your web application
from the command line.

-pate


Bruce Williams
bruce@codedbliss.com

I was really wowed by Narf at RubyConf. It’s got built in templating,
reasonable looking HTML generation, CGI bits, and (best of all) it’s got
test::Unit hooks built in allowing you to easily test your web application
from the command line.

-pate

Actually, NARF is one of the libraries on my list to check out. But I’m not
sure I’d switch to NARF templating; I’m quite fond of Amrita’s pure xhtml
templating capability and the Amrita::ExpandByMember mixin. That said, I
certainly look forward to using NARFs CGI bits.

One of the things Tom and Patrick said that really intrigued me is that
they want to make the templating pluggable. Perhaps you could pester them
to look at Amrita’s style.

-pate

···

On Sun, 10 Nov 2002, Bruce Williams wrote:

On Saturday 09 November 2002 12:50 pm, Pat Eyler wrote:


Bruce Williams
bruce@codedbliss.com

I took a look at it - looks interesting. Narf and the templating system
are fairly well decoupled, so it could be pretty easy to disconnect. All I
need a is a way of figuring out which code to run.

I was considering using file extensions as a way of differentiating
between different types of templates, as opposed to specifically
instantiating something.

What do you think?

-Tom

···

On Sun, 10 Nov 2002, Pat Eyler wrote:

On Sun, 10 Nov 2002, Bruce Williams wrote:

On Saturday 09 November 2002 12:50 pm, Pat Eyler wrote:

I was really wowed by Narf at RubyConf. It’s got built in templating,
reasonable looking HTML generation, CGI bits, and (best of all) it’s got
test::Unit hooks built in allowing you to easily test your web application
from the command line.

-pate

Actually, NARF is one of the libraries on my list to check out. But I’m not
sure I’d switch to NARF templating; I’m quite fond of Amrita’s pure xhtml
templating capability and the Amrita::ExpandByMember mixin. That said, I
certainly look forward to using NARFs CGI bits.

One of the things Tom and Patrick said that really intrigued me is that
they want to make the templating pluggable. Perhaps you could pester them
to look at Amrita’s style.

-pate


Bruce Williams
bruce@codedbliss.com

I suppose that would be a good approach-- and I guess you could handle inline
templates specifically. It should be pretty easy to write, just requiring
amrita/template and using either Amrita::TemplateFile or
Amrita::TemplateText. Of course, this is just supposition on my part…

Being able to use Amrita from NARF “out of the box” would definitely be
something I’d be interested in doing, since I plan on using both anyway. :slight_smile:
Let me know if you want anyone to test/plug away away at it.

Thanks-

···

On Saturday 09 November 2002 05:07 pm, Tom Clarke wrote:

I was considering using file extensions as a way of differentiating
between different types of templates, as opposed to specifically
instantiating something.

What do you think?

-Tom


Bruce Williams