Search code examples
htmlruby-on-railsrubypartialmiddleman

Repeat calls inside Ruby partial


I'm new to Ruby, so this may be straight forward. I have a partial which I want to essentially populate a list.

Here's my partial (.erb) code:

<ul>
  <% if locals.has_key? :sermon_commentary %>
    <li><i class="material-icons">link</i><a href="<%= sermon_commentary %>">Matthew Henry's Commentary on <%= sermon_passage %></a></li>
  <% end %>
  <% if locals.has_key? :sermon_passage_lookup %>
    <li><i class="material-icons">link</i><a href="<%= sermon_passage_lookup %>"><%= sermon_passage %> on Bible Gateway</a></li>
  <% end %>
  <% if locals.has_key? :sermon_audio_download %>
    <li><i class="material-icons">music_note</i><a href="/audio/<%= sermon_audio_download %>" download="/audio/<%= sermon_audio_download %>">Download this sermon (MP3 ~5mb)</a></li>
  <% end %>
</ul>

And here's how I'm calling it in a .html.erb file:

  :sermon_commentary => "https://www.biblegateway.com/resources/matthew-henry/Luke",
  :sermon_passage_lookup => "https://www.biblegateway.com/passage/?search=Luke+4%3A14-21&version=NIV",
  :sermon_audio_download => "FUSE_7th_August.mp3",
  :sermon_video => "https://www.youtube-nocookie.com/embed/VzOYe8nUCS4?rel=0&amp;showinfo=0"

However with the current code above, if I want multiple list items (say, a second 'sermon_passage_lookup' list item, it doesn't work.

Any help would be appreciated. I think I need a

[something].each do |something|

But I'm not sure how to structure it. Thanks :)

EDIT: Implementing Taryn's fix

Thanks for all your help so far, Taryn. I now see the distinct differences between the hash and the array. I've set my partial template as per your suggestion:

<ul>
  <% if locals.has_key? :sermon_links %>
    <% sermon_links.each do |link| %>
      <li>
        <i class="material-icon‌​s"><%= link[:icon] %></i>
        <a href="<%= link[:hyperlink] %>"><%= link[:link_label] %></a>
      </li>
    <% end %>
  <% end %>
</ul>

And I'm using it as such:

:sermon_links => [
   { :icon => "link", :hyperlink => "http://www.facebook.com/", :link_label => "Testing" },
   { :icon => "link", :hyperlink => "http://google.com/", :link_label => "Testing2" }
 ]

Unfortunately I'm getting errors. Looks like the 'link' hash isn't being recognised? Here's what Chrome throws at me:

NameError at /resources/sermons/the-fifth-act/fuse-14-08-16.html undefined local variable or method 'icon' for #<Middleman::Application:0x70168621815860>


Solution

  • if you make sure you pass in the sermon_passage_lookups as an array (even if there's one item) then you can call each on them just as you mention eg:

    <% if locals.has_key? :sermon_passage_lookups %>
      <% sermon_passage_lookups.each do |sermon_passage_lookup| %>
        <li><i class="material-icons">link</i><a href="<%= sermon_passage_lookup %>"><%= sermon_passage %> on Bible Gateway</a></li>
      <% end %>
    <% end %>
    

    EDIT

    a variation on your example given in the comments below:

    Firstly the main .erb template: I think you don't need the redundant word :link here -> just put each link-set into the main array. Also you don't need the extra array around the link-hash eg all you need is:

    :sermon_links => [
       { :icon => "link", :hyperlink => "http://www.facebook‌​.com/", :link_label => "Testing" },
       {:icon => "link2", :hyperlink => "http://google.com/", :link_label => "Testing2"} ]
    

    ie include just the data you need, and nothing you don't.

    This is a hash with the key of sermon_links and the value is an array. The array contains hashes - each one corresponding to the link-data you need to list.

    Then, your partial template will need to access these hashes from the sermon_links array. Your example in the comments is treating the values of the hash as though they are variable-name (eg <%= icon %>) but that won't work... the only variable is named sermon_links which you then use each to turn each value into a single hash which you are naming link, so you need to reference link as a hash to get the icon out of it... like this:

    <ul>
      <% if locals.has_key? :sermon_links %>
        <!-- at this point we have the full `sermon_links` -->
        <% sermon_links.each do |link| %>
          <!-- now we have a single `link` from the set eg
             - { :icon => "link",
                 :hyperlink => "http://www.facebook‌​.com/",
                 :link_label => "Testing" } -->
          <li>
            <i class="material-icon‌​s"><%= link[:icon] %></i>
            <a href="<%= link[:hyperlink] %>"><%= link[:link_label] %></a>
          </li>
        <% end %>
      <% end %>
    </ul>