How to use Haml in your helpers

Updated . Posted . Visible to the public.

You know those helper methods that just render some HTML but look weird because of content_tags all over the place? You could also use Haml instead.

Example

Consider the following helper.

def greeting
  message = ''.html_safe
  message << 'Welcome to '
  message << content_tag(:span, Rails.env, class: 'greeting--location')
  content_tag :div, message, class: 'greeting'
end

That looks clumsy and is hard to read.

Wouldn't it be nicer to say something like this?

def greeting
  render_haml <<-HAML
    .greeting
      Welcome to
      %span.greeting--location
        = Rails.env
  HAML
end

It would be, and you can have it, too. You simply need to define render_haml as a helper method:

def render_haml(haml, locals = {})
  Haml::Engine.new(haml.strip_heredoc, format: :html5).render(self, locals)
end

Note how we pass the helper method's view context (self). This means that all of your other helper methods will be available to your Haml fragment.

Also note that you can pass locals to your Haml templates as usual:

def greet(someone)
  render_haml <<-HAML, name: someone
    Hello
    %strong
      = name
  HAML
end

Enjoy. :)


Full disclosure: The solution above loads and evaluates your Haml "template" each time which might have a negative impact on your application's performance. We did not yet benchmark it, but using it for elements that are rendered very often is probably a bad idea.

Arne Hartherz
Last edit
Arne Hartherz
License
Source code in this card is licensed under the MIT License.
Posted by Arne Hartherz to makandra dev (2016-09-16 13:08)