HAML: RoR's new templating engine

I forgot one big thing.

I am considering multi-single line support.

That is…

%div= link_to :action => “logoff”, |
:id => @user.id, |
:message=> “message” |

Doing the pipes on the end to put together single-evaluated lines.

In theory, if that was implemented, then blocks could be possible.
However, I generally want to stay away from that: see the previous
posts.

(Also, form_for would never work, since I’m not using erb, without
re-writing. multi-line or not.)

-hampton.

I agree. I think this looks really promising and would love to be
able to use it. unfortunately I don’t think its realistic to now
allow multi line iterations.

Ezra-

Great questions from you guys. I’m really glad that you guys are zooming
right in there with questions I asked myself many, many, many times.

It really comes down to the fact that blocks in views have always been a
red-flag for me as far as quality of code and readability.

The long term approach for the form_for block is to allow its use in the
helpers. So, I might have a helper like this for a form.

def person_form(person)
form_for(person) do |f|
f.text_area(:name)
f.date_select(:birthday)
f.submit_tag
end
end

Then, when I build my page, it might look like this.

signup.haml

%p
My site really rocks!
.signup
%p Please fill out the form below to sign up!
#form_area= person_form()

Or heck, just write it yourself using the old helpers.

But, that being said, I’m open to suggestions. The no-block rule has
worked out several times very well to produce simple-looking code with
complex rules that gets hidden and broken up in a few ways.

There is the “More than 10 lines a method is bad” school of thought, and
I’m not necissarily disagreeing this way. Why are we ok with 40 line
views??

-hampton.

PS: So, I need to override the form_for to get it working without an ERB
object, since right now its specific to ERB. That’s on the todo list.
Patches for that would be fantastic!

Ezra Z. wrote:

I agree. I think this looks really promising and would love to be
able to use it. unfortunately I don’t think its realistic to now
allow multi line iterations. I may have a look and patch this in
though. Was it left out because it was hard to implement or because
the authors really don’t think its needed? I really like the looks of
these templates but no multi line loops is a show stopper for me.

+1 for me too. I’m not interested in creating partials for each and
every each loop (which would result in my templates really multiplying),
nor putting the loop into a helper which outputs via Ruby not template
markup or rhtml (yuck).

Joe

It’s a paradigm shift all right. For example,

---------hello.haml--------
!!!
%html
%head
%title this is the title
%body
hello world
%ul= render :partial => ‘list_item’, :collection => @members

---------_list_item.haml---------
%li= list_item.member_name

I’m going to have to dig into what this means when you get into
pagination
and such. I use blocks for so much stuff in rhtml it would hurt not to
have
them. I think elimination of blocks might break the direction Rails is
going
but I don’t know for sure…

Steve

Ezra Z.-3 wrote:

HAML had a


View this message in context:
http://www.nabble.com/HAML%3A-RoR's-new-templating-engine-tf2268612.html#a6312632
Sent from the RubyOnRails Users forum at Nabble.com.

---------hello.haml--------
!!!
%html
%head
%title this is the title
%body
hello world
%ul= render :partial => ‘list_item’, :collection => @members

---------_list_item.haml---------
%li= list_item.member_name

No, that would be bad.

This will be committed soon.

!!!
%html
%head
%title this is the title
%body
hello world
%ul= list_items(@members) &:login
%ul= list_items(@members) { |m| “#{m.last_name}, #{m.first_name}” }

Like I said though, I’m open to suggestions. I just suggest that anyone
reading this… install the plugin, and convert just one template. Its
rather easy. Just change the extention and play with it.

Though, I am always open to reconsidering.

-hampton.

Can you characterize “bad” (as in, “that would be bad”)? I’m finding it
pretty easy to convert templates, although I ran up against one that had
a file-column in it that required some messing around:

= @catalog_item = catalog_item;

link_to(image_tag(url_for_file_column(“catalog_item”, “image”,
“thumb”)),
{:action => ‘enlarge’, :id => catalog_item}, :popup => [‘new window’])

Joe-95 wrote:

%ul= render :partial => 'list_item', :collection => @members

!!!
reading this… install the plugin, and convert just one template. Its
rather easy. Just change the extention and play with it.

Though, I am always open to reconsidering.

-hampton.


View this message in context:
http://www.nabble.com/HAML%3A-RoR's-new-templating-engine-tf2268612.html#a6316390
Sent from the RubyOnRails Users forum at Nabble.com.

Heads up: run the tabs to spaces command in textmate, even if you are
using soft-tabs. Maybe I misunderstand that term, but it led me to a
while of frustration ‘til I realized what was up. Yay whitespace
lovin’.

So, I’m thinking it shouldn’t need me to declare which html elements
are self-terminating. But we can leave in the option for
self-termination at will, of course. I was also thinking % with no
identifer could be considered as %p.

What about an inline syntax:

% Hi. Um… I {em really}, {strong really} like you. Okay.

Also, why not use ActionView::Helpers::TagHelper? It already handles
the basic tag creation in a simple way, and does escaping and such.

OK, i have > 30 controllers, with hundreds of views. Can you imagine
all the work it would requrie to create sub-views for all my control
loops!? I use rails to be speedy and efficient.

It’s a pity HAML is doing this, otherwise it could be a massively used
templating system.

I agree with everything Seth pointed out. Why not let any amount of
(non-newline) whitespace denote a new block, rather than only two
spaces?

I’d also like to add my voice to those who feel that adding support for
Ruby blocks would be a good idea. If you also added some character, say
‘-’, that denoted code that was executed but not used as output, then
you could do something like:

  • for foo in @foolist
    %h1 foo.name
    %p foo.text

I echo this.

Have started using HAML for a major project, as it is simply beautiful.

However, I’m not going to write a partial for every tiny loop: it would
be madness.

Neither do I want to mess around with generating layout from a helper
object. Isn’t that what views are for ?

Although I understand that ‘code in views’ == bad, surely the
equivalent of “take this collection of things (which were collected
together somewhere else) and show each one like this” is more markup
than code ?

I’m now in the curious position of using HAML for pretty much
everything, and calling in an rhtml partial when I need to pump out a
list. Hardly ideal…

Terry

I’m not against using the - to mean “eval but don’t print anything”.
However, the problem is the way that its all parsed and executed. We
might be able to work something out, but the deal is that each line is
currently evaluated in-itself.

I was unclear in my post.

This should mean… I’m not against the “-” then I start talking about
blocks and how complex implementing them could be.

I really should read my posts over once before I hit the submit button.

-hampton.

Nex3 wrote:

I agree with everything Seth pointed out. Why not let any amount of
(non-newline) whitespace denote a new block, rather than only two
spaces?

I’d also like to add my voice to those who feel that adding support for
Ruby blocks would be a good idea. If you also added some character, say
‘-’, that denoted code that was executed but not used as output, then
you could do something like:

  • for foo in @foolist
    %h1 foo.name
    %p foo.text

I’m not against using the - to mean “eval but don’t print anything”.
However, the problem is the way that its all parsed and executed. We
might be able to work something out, but the deal is that each line is
currently evaluated in-itself.

I’m not sold on the idea that this is a good thing and the
implementation would become much more complex.

However, I still haven’t seen any arguements on why this is a Good
Thing, beyond forces of habit, and that some rails helpers use it.
Tradition isn’t a good arguement.

In the three fairly-complex projects I have done in HAML, besides
breaking habit, I haven’t really needed blocks. The closest I got was
a pang of rememberance for how i’d do it in rhtml.

I am listening though, and thinking about this very carefully. I’m more
open to arguements about how people have hit certain problems and can’t
solve them with nice-looking code… and there aren’t any alternate
helpers that could be made to simplify things.

-hampton.

itsterry wrote:

Although I understand that ‘code in views’ == bad, surely the
equivalent of “take this collection of things (which were collected
together somewhere else) and show each one like this” is more markup
than code ?

It’s presentation logic, not really “code”. Things like:

unless session[:member].nil?
text “Hello #{session[:member].name}!”
end

Joe

Chris wrote:

OK, i have > 30 controllers, with hundreds of views. Can you imagine
all the work it would requrie to create sub-views for all my control
loops!? I use rails to be speedy and efficient.

It’s a pity HAML is doing this, otherwise it could be a massively used
templating system.

I enjoyed Hampton’s presentation at RailsConf yesterday, and I’ve just
read through the whole of this thread.

One thing that strikes me is that Rails has an asymmetry between the use
of files for helpers (where you can put many helpers in one file), and
the use of files for partials (where you have have one file per
partial). I get the impression that in Chris’s case this would lead to
an unmanageable mass of tiny files.

Would it be possible for HAML partials to get away from the “one file
per partial” constraint? It would be good to be able to use named
template fragments, defined either in the file that is using them or in
a fragment library file looked up by convention (or explicitly
imported).

In programming, it’s a good idea to factor out a new method wherever you
can put a meaningful name to a bunch of lines in an existing method. You
wouldn’t dream of doing this if every method had to live in its own
file. Shouldn’t the same principles apply to templates?

regards

Justin F.

In programming, it’s a good idea to factor out a new method wherever you
can put a meaningful name to a bunch of lines in an existing method. You
wouldn’t dream of doing this if every method had to live in its own
file. Shouldn’t the same principles apply to templates?

Now that is a smart thought !

On Sep 15, 2006, at 5:31 AM, Hampton Catlin wrote:

‘-’, that denoted code that was executed but not used as output, then
you could do something like:

  • for foo in @foolist
    %h1 foo.name
    %p foo.text

I’m not against using the - to mean “eval but don’t print anything”.
However, the problem is the way that its all parsed and executed. We
might be able to work something out, but the deal is that each line is
currently evaluated in-itself.

So this seems more like an implementation issue rather then there is
no reason to allow it right? I really like your syntax but I think
you will keep getting pushback until multi line iterations and if
statements are allowed. I looked at the codebase and I don’t think
it would be too hard to add a little state to the parse loop to keep
track of multi line statements and eval them accordingly.

I’m not sold on the idea that this is a good thing and the
implementation would become much more complex.

However, I still haven’t seen any arguements on why this is a Good
Thing, beyond forces of habit, and that some rails helpers use it.
Tradition isn’t a good arguement.

What about <% cache do %> blocks? what about content_for :sidebar
blocks? there are really a ton of useful situations where the blocks
in a view are very important.

Couldn’t you do some look ahead when parsing the template? You
already are loading all the lines into memory before processing with
this line:

template.split(/\n/).map do |line|

What about preprocessing the template to combine multi line
statements starting with == into one line statements starting with =
and with the compressed lines separated with ;

so this:

%body
#posts
== @posts.each do |post|
== link_to post.title, :action => ‘foo’, :id => post
== end

becomes this internally after preprocessing before parsing:

%body
#posts
= @posts.each do |post| ; link_to post.title, :action =>
‘foo’, :id => post ; end

Some stupid code that does this preprocessing:

   buffer = []
   seen = false
   last = false
   template.each_with_index do |line, index|
     if line.strip =~ /^==/
       unless seen
         buffer << line.sub(/==/,'=').chomp
         last = index
         seen = true
       else
         buffer[last] << ';'+line.sub('==', '').strip
       end
     else
       seen = false
       buffer << line
     end
   end

And then go into your normal parse loop now that the multi line
statements are compressed to single line statements? I am sure there
is a better way to do it but this seems feasible.

In the three fairly-complex projects I have done in HAML, besides
breaking habit, I haven’t really needed blocks. The closest I got
was
a pang of rememberance for how i’d do it in rhtml.

Maybe you haven’t needed block because you weren’t allowed to do
them :wink: I think HAML is truly something very cool, I just think it
won’t get as much adoption as it should until you allow multi line
statements period.

just my two cents here of course…

Cheers-
-Ezra

Justin F. wrote:

Would it be possible for HAML partials to get away from the “one file
per partial” constraint? It would be good to be able to use named
template fragments, defined either in the file that is using them or in
a fragment library file looked up by convention (or explicitly imported).

This idea needs further exploration… I like it. The concept reminds
me a bit of XSL templates: you would usually have many per file, but
HAML would of course have a different mechanism for including the
partials.

Here’s an example XSL file if you’ve never seen one:
http://www.brics.dk/~amoeller/XML/xslt-4.1.html

John Philip G.

HI, does this new template engine code work well within Dreamweaver?
I have had very good success with RHTML code within DW.

Thanks,

-Conrad

I have been following this thread, though not too closely so I may have
missed
some of the following points.

  1. My first impression is HAML is so “leading edge” that current editors
    don’t
    have any support for it yet.

  2. Although RHTML isn’t “special” or “better” than ASP, JSP and the
    likes. However,
    besides good compatibility, vanilla HTML do not need further processing.
    In HAML
    just about every line needs to be transformed (HAML -> HTML or
    whatever). This
    beg the question of performance. Are there performance issues we should
    be concerned
    about?

  3. HAML perhaps may be easily learned but I wonder how well this works
    in practice.
    It is another layer of abstraction web designers/authors will need to
    deal with. I am not
    sure how well HAML will be accepted in their world.

Long

Justin-

Now, that’s along with my thinking.

Very soon we will indeed have multi-line statements. I’m going to make
it clear that I think 99% of the loops in views are crap and are
against HAML style.

However, I have wanted to be able to say this.

#links
= link_to “signup”, |
:action => “go” |
:id => @id |

I think this looks ok and works great for hashs and making stuff look
good by taking one line and making it go on multiple. That being said,
you could do a loop, though, I really don’t recommend it most places.

Now, on to what you said! Your point that we need another solution
is exactly what I’m thinking about these days. The fact is that
ApplicationHelpers are weird things. They seem to be where you put it
when you don’t have any other idea of where it should go.

DHH said something in his talk that really hit me. “When you fix one
thing, you notice how broken something else is!” That’s exactly my
opinion. I think that haml’s general restraints (Good Thing) just show
the awkwardness of Helpers at the moment. Or whatever it is that we
can think of that might be better.

One of the solutions I’m thinking of are Markaby fragments. I wish I
could have a backup file of markaby fragments that I can call and use
to describe the little bits that I’m now putting in helpers.

I think the views themselves are better now, now is time to turn our
attention towards new, totally crazy, rebellious ideas for helpers and
fragments.

Please email me directly with your thoughts.

[email protected]

Thanks,
Hampton.