HAML partial IF/ELSE, how can I DRY this up?

Can I do it without resorting to making another partial to contain the %span content below?

partial begin

  • if defined(skipLI) && skipLI %span this is not DRY

  • else


%span this is not DRY

partial end

Try content_for maybe? Usually it’s used for passing snippets up the template chain, but it would probably work in this case as well.

  • content_for(:not_dry) do

%span this is not DRY

  • if defined?(skipLI) && skipLI

  • yield :not_dry

  • else


  • yield :not_dry

One idea off the top of my head:

Create a helper method and use content_tag

def give_it_to_me html_content = content_tag(:span, ‘This is DRY’)

defined?(skipLI) && skipLI ? html_content : content_tag(:li, html_content) end

I think this will work.



Had to change from - yield to = yield.


Thanks. I was hoping to not have to pull the code out in to another file. Not sure if I would have been able to define a method inside the same haml file or not. The yield suggestion seems to have worked in any case.

Thanks, it's good. I had the same problem with links instead of li, and I've encountered link_to_if in the reference:

=link_to_if make_link, url_for(...) do   this is dry :smiley:

You could see the source of link_to_if (and link_to_unless) to see how to implement it for %li's if you want to.

Also, I've just found capture:

- not_dry = capture do   %span This is not dry - if defined?(skipLI) && skipLI   =not_dry - else   %li     =not_dry

Bernat Kallo wrote in post #1012148:

=link_to_if make_link, url_for(...) do   this is dry :smiley:

No, it's wrong :blush: this is not the way link_to can be used

Another option is to create a generic helper:

def wrap_with_li_if(condition, content = nil, &block) if block_given? content = capture(&block) end
return content_tag(:li, content) if condition return content end

Then you can use it like so:

= wrap_with_li_if(defined?(skipLI) && skipLI) do %span This is not DRY


  • notDRY = “This is not DRY” = wrap_with_li_if(defined?(skipLI) && skipLI, notDRY)

Now that I’m thinking about it, you can maybe even make it more generic if you like. I can actually think of a few places in my own code this would come in handy:

def content_tag_if(condition, tag, content = nil, &block) if block_given? content = capture(&block) end
return content_tag(tag, content) if condition return content end

= content_tag_if(defined?(skipLI) && skipLI, :li) do %span This is not DRY