Roberto Pezzali
Roberto Pezzali

Reputation: 2494

Insert HAML into a Sinatra helper

I'm writing a helper for a small Sinatra app that prints some gaming cards stored as hash in an array.

Every card has this structure:

{ card: 'Ace', suit: :spades, value:  11 }

and the filename of the card image is "spades_11.jpg".

I'm writing a helper to display the cards in my view:

def view(hand)
  hand.each do |card|
    #print the card
  end   
end

I need an output like this:

.span2
  %img(src="/images/#{card[:suite]}_#{card[:value]}")

How can I insert my Haml code inside the helper block keeping the indentation?

Upvotes: 2

Views: 706

Answers (2)

matt
matt

Reputation: 79733

The simplest solution would be to just return the HTML directly from your helper as a string:

def view(hand)
  hand.map do |card|
    "<div class='span2'><img src='/images/#{card[:suite]}_#{card[:value]}'></div>"
  end.join 
end

The call it from your Haml with something like:

= view(@the_hand)

You could make use of the haml_tag helper which would let you write something like:

def view(hand)
  hand.each do |card|
    haml_tag '.span2' do
      haml_tag :img, 'src' => "/images/#{card[:suite]}_#{card[:value]}"
    end
  end   
end

Note that haml_tag writes directly to the output rather than returning a string, so you would have to use it with - rather than =:

- view(@the_hand)

or use capture_haml.

This method means your helper depends on Haml. The first method would be usable whatever template language you used, but wouldn’t respect settings like format for whether to end the img tag with />.

If you want to use pure Haml for the markup for each card (this example is simple enough to get away with helpers, but you would certainly want to do this for more complex sections) you could use a partial. Add you Haml code to a file named e.g. view.haml, then you can render it from the containing template, passing in the hand as a local variable:

view.haml:

- hand.each do |card|
  .span2
    %img(src="/images/#{card[:suite]}_#{card[:value]}")

Parent template:

= haml :view, :locals => {:hand => @the_hand}

Upvotes: 2

Alex.Bullard
Alex.Bullard

Reputation: 5563

You should be able to use a here doc

def view(hand)
  hand.each do |card|
    <<-HAML
.span2
  %img(src="/images/#{card[:suite]}_#{card[:value]}")
    HAML
  end   
end

but note that here docs take the whitespace from the start of the line the are on, so unfortunately this will make your indentation somewhat ugly.

For anything more complicated it probably makes sense to write your haml in a separate .haml file.

Upvotes: 2

Related Questions