Search code examples
ruby-on-railstemplatesdjango-templatesequivalent

'spaceless' equivalent of Django templates in Rails


Notice the readability and balance of:

<li class='aclass anotherclass <%= maybeaconditionalclass %>'>
   <a href="<%= some stuff %>">
     <%= some other stuff %>
   </a>
</li>

which unfortunately produces trailing whitespace inside the link resulting in a ugly trailing underline. Now although less readable I can live with this:

<li class='apossibleclass anotherclass <%= maybeaconditionalclass %>'>
   <a href="<%= some stuff %>"><%= some other stuff %></a>
</li>

Still, the same problem remains if I now consider this kind of thing:

li.apossibleclass:after {
    content: "/";
}

as the whitespace between the closing A and LI gets in the way of what should be sticking to my list item's end. I could only produce that ugly mess as a workaround:

<li class='apossibleclass anotherclass <%= maybeaconditionalclass %>'>
   <a href="<%= some stuff %>"><%= some other stuff %></a></li>

Django came up with a nice solution: {% spaceless %}, so I'm looking for the equivalent of the {% spaceless %} tag in Rails erb templates.


Solution

  • Yes, that would be an useful feature, and as far as I know, there's nothing like it in Rails. So I've coded it.

    # Strip all whitespace between the HTML tags in the passed block, and
    # on its start and end.
    def spaceless(&block)
      contents = capture(&block)
    
      # Note that string returned by +capture+ is implicitly HTML-safe,
      # and this mangling does not introduce unsafe changes, so I'm just
      # resetting the flag.
      contents.strip.gsub(/>\s+</, '><').html_safe
    end
    

    This is a helper you can place in your application_helper.rb, and then use like this:

    <%= spaceless do %>
      <p>
          <a href="foo/"> Foo </a>
      </p>
    <% end %>
    

    ... which will result in the output string like

    <p><a href="foo/"> Foo </a></p>
    

    Sadly, this only works in Rails 3. Rails 2 support for a feature like this will require some dirty hacks to ERb.