Multiple multi-line HAML blocks

Matchu picture Matchu · Sep 25, 2009 · Viewed 26.1k times · Source

Using the (intentionally) strange multi-line format for HAML, I'd like to have the following lines in my template:

= call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3', |
  :foo4 => 'bar4', :foo5 => 'bar5' |

-# and

= call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3', |
  :foo4 => 'bar4', :foo5 => 'bar5' |

However, they can not run up against one another, or they are read as one single multi-line block.

-# This fails:
= call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3', |
  :foo4 => 'bar4', :foo5 => 'bar5' |
= call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3', |
  :foo4 => 'bar4', :foo5 => 'bar5' |

And separating with a line break, interestingly enough, does no better:

-# This fails, too:
= call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3', |
  :foo4 => 'bar4', :foo5 => 'bar5' |

= call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3', |
  :foo4 => 'bar4', :foo5 => 'bar5' |

The only working solution I have found is to run a blank line of Ruby code between. Which looks really ugly.

= call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3', |
  :foo4 => 'bar4', :foo5 => 'bar5' |
-
= call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3', |
  :foo4 => 'bar4', :foo5 => 'bar5' |

Is there anything better?

Answer

Natalie Weizenbaum picture Natalie Weizenbaum · Sep 25, 2009

This is a feature, not a bug. Haml multiline blocks are intentionally unwieldy - including hard to follow one after another - because almost all the time it's better to put that Ruby code into a helper. Even if the helper is only called once, it will make your template much easier to read. For instance:

def blatz_link
  call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3',
    :foo4 => 'bar4', :foo5 => 'bar5'
end

def blootz_link
  call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3',
    :foo4 => 'bar4', :foo5 => 'bar5'
end

Then in your Haml, just do

= blatz_link
= blootz_link

which will be much more readable and easier to understand.


If you absolutely must follow one multiline block with another, just add a comment in between:

= call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3', |
  :foo4 => 'bar4', :foo5 => 'bar5' |
-#
= call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3', |
  :foo4 => 'bar4', :foo5 => 'bar5' |