Search code examples
ruby-on-railsrubyhelper

How to wrap links into ul li in Ruby?


My apologize for syntactic illiteracy, I didn't have to deal with Ruby, but it is necessary to wrap links in the ul> li list (ul>li>a instead of a)

def links_to_hashtags(hashtags = object.hashtags)
  hashtags.map(&:to_s).map do |hashtag|
    # XXX transitional
    url = h.hashtag_page_enabled? && h.logged_out? ? h.tag_path(hashtag.downcase) : h.hashtag_friends_path(q: hashtag.downcase)
    h.link_to "##{hashtag}", url, dir: h.html_dir(hashtag)
  end.join(' ').html_safe
end

I tried this way but it has some syntax errors:

def links_to_hashtags(hashtags = object.hashtags)
  hashtags.map(&:to_s).map do |hashtag|
    # XXX transitional
    url = h.hashtag_page_enabled? && h.logged_out? ? h.tag_path(hashtag.downcase) : h.hashtag_friends_path(q: hashtag.downcase)
    h.content_tag :ul, class: 'fancy' do
    h.concat h.content_tag :li,
    h.link_to "##{hashtag}", url, dir: h.html_dir(hashtag)
  end.join(' ').html_safe
end   

Many thanks for thе response!


Solution

  • def links_to_hashtags(hashtags = object.hashtags)
      h.content_tag :ul, class: 'fancy' do
        hashtags.map(&:to_s).each do |hashtag|
          concat h.content_tag :li do
            concat link_to_hashtag(hashtag)
          end
        end
      end  
    end
    
    def link_to_hashtag(hashtag)
      # prefer if ... else over unreadably long ternary expressions
      url = if h.hashtag_page_enabled? && h.logged_out? 
        h.tag_path(hashtag.downcase) 
      else 
        h.hashtag_friends_path(q: hashtag.downcase) 
      end
      h.link_to ['#', hashtag].join, url, dir: h.html_dir(hashtag)
    end
    

    Each of the content helpers like content_tag creates its own string buffer. When you use concat in the block you're writing into the buffer of that tag - just like when you use <%= in ERB. This removes the need to do clunky string concatenation and deal with the html tags getting escaped.

    However this really is something that your should consider using a partial for instead.

    <ul class="fancy">
      <% hashtags.each do |hashtag| %>
        <li><%= link_to_hashtag(hashtag) %></li>
      <% end %>
    </ul>