39

How can I use a condition to decide whether to output a surrounding tag in HAML? I'm trying to create the DRY version of the code below.

- if i_should_link 
  %a{:href => url}
   .foo
     .block
       .of  
         .code
- else
  .foo
    .block
      .of  
        .code
Nathan Long
  • 122,748
  • 97
  • 336
  • 451
Sean Ahrens
  • 1,025
  • 1
  • 9
  • 18

2 Answers2

36

You could use a partial.

foo.html.haml

- if i_should_link
  %a{:href => url}
    = render 'bar'
- else
  = render 'bar'

_bar.html.haml

.foo
  .block
    .of
      .code

Edit: Or you could use content for, I guess this is better because it keeps it all in the same file.

- if i_should_link
  %a{:href => url}
    = yield :foobar
- else
  = yield :foobar

- content_for :foobar do
  .foo
    .block
      .of
        .code
twe4ked
  • 2,832
  • 21
  • 24
27

I think odin's suggestion to use a partial is probably the best in most situations.

However, as an alternate solution, I found a thread where Nathan Weizenbaum suggested defining this method:

def haml_tag_if(condition, *args, &block)
  if condition
    haml_tag *args, &block
   else
     yield
   end
end

Whatever is in the block would always be rendered, but the wrapping tag would appear or not based on the condition.

You would use it as follows:

- haml_tag_if(planning_to_mail?, :div, :id => 'envelope') do
   %p I'm a letter

If planning_to_mail? evaluates true, you'd get:

<div id="envelope">
  <p>I'm a letter</p>
</div>

If it evaluates false, you'd get:

<p>I'm a letter</p>

He floated the idea of adding this to Haml::Helpers, but that doesn't appear to have happened yet.

Nathan Long
  • 122,748
  • 97
  • 336
  • 451
  • 10
    This has recently been added to Haml, but it isn’t yet in a release. Look out for it in Haml 4.1 or Haml 5: https://github.com/haml/haml/commit/66a8ee080a9fb82907618227e88ce5c2c969e9d1 – matt Apr 29 '13 at 20:00
  • This is a fantastic answer - six years on and still offering a great solution. For what it's worth, I've replaced haml_tag with content_tag in the helper and it works just as outlined above. – SRack Dec 07 '17 at 16:15
  • 1
    The `haml_tag_if helper` method mentionned in the comment above should be the accepted answer, many thanks! – Renaud Chaput Apr 07 '18 at 14:42