Helper Methods

Template helpers are methods which can be used in your dynamic templates to simplify common HTML tasks. Most of the basic methods should be very familiar to anyone who has used rails view helpers. These helpers are all built on the Padrino Framework, view the full documentation here.

Padrino provides a link_to function that you can use to make link tags. At its most basic, link_to takes the name and URL of a link:

<%= link_to 'My Site', 'http://mysite.com' %>

link_to can also take a block, allowing you to provide more complex content for the link:

<% link_to 'http://mysite.com' do %>
  <%= image_tag 'mylogo.png' %>
<% end %>

Middleman enhances the link_to helper to be aware of the sitemap. If you refer to pages in your source folder (with their file extension minus all the template extensions) then link_to will generate the correct link, even if you have extensions like :directory_indexes on. For example, if you had a file source/about.html and :directory_indexes on, you could link to it like this:

<%= link_to 'About', '/about.html' %>

Produces:

<a href='/about/'>About</a>

You can also refer to source paths relative to your current page. Some people want their links to be relative to the current page. Pass :relative => true to link_to to get a relative URL.

From within source/foo/index.html.erb, with :directory_indexes on:

<%= link_to 'About', '/about.html', :relative => true %>

Produces:

<a href='../about/'>About</a>

If you want all URLs generated by link_to to be relative, add this to config.rb:

set :relative_links, true

You can still override individual links to not be relative by adding :relative => false.

If the link_to helper fails to determine which page the URL provided belongs to, it will use the URL without modifying it. The :relative_links option will be ignored in this case, but the :relative => true argument will produce an error.

Note that the url method of the Sitemap Resource (also inherited by Blogging BlogArticle) returns an output URL. The link_to helper may be unable to match it to a source path of the corresponding page/article and thus will be unable to convert it to a relative URL.

Instead of providing the output url for link_to, provide either the source path via Resource/BlogArticle path attribute or simply pass the resource itself as the URL argument for link_to. Both will have link_to produce relative URLs:

<ul>
  <% blog.articles.each do |article| %>
    <li>
      <%= link_to article.title, article.path, :relative => true %>
      <%# Note `article.path` in the second argument %>
    </li>
  <% end %>
</ul>

<ul>
  <% sitemap.resources.select{|resource| resource.data.title}.each do |resource| %>
    <li>
      <%= link_to resource.data.title, resource, :relative => true %>
      <%# Note `resource` in the second argument %>
    </li>
  <% end %>
</ul>

You can include query parameters or URL fragments in your links as well:

<%= link_to 'My Form', '/form.html', :query => { :foo => 'bar' }, :fragment => 'deep' %>

Produces:

<a href='/form.html?foo=bar#deep'>My Form</a>

If you just want the URL to a page without the link tag, use url_for. It powers all the magic in link_to, and is used in form_tag as well.

Output Helpers

Output helpers are a collection of important methods for managing, capturing and displaying output in various ways and is used frequently to support higher-level helper functions. There are three output helpers worth mentioning: content_for, capture_html, and concat_content.

The content_for functionality supports capturing content and then rendering this into a different place such as within a layout. One such example is including assets onto the layout from a template:

<% content_for :assets do %>
  <%= stylesheet_link_tag 'index', 'custom' %>
<% end %>

Added to a template, this will capture the includes from the block and allow them to be yielded into the layout:

<head>
  <title>Example</title>
  <%= stylesheet_link_tag 'style' %>
  <%= yield_content :assets %>
</head>

This will automatically insert the contents of the block (in this case a stylesheet include) into the location the content is yielded within the layout.

You can also check if a content_for block exists for a given key using content_for?:

<% if content_for?(:assets) %>  
  <div><%= yield_content :assets %></div>
<% end %>

Also supports arguments yielded to the content block

yield_content :head, param1, param2
content_for(:head) { |param1, param2| ...content... }

Tag Helpers

Tag helpers are the basic building blocks used to construct html "tags" within a view template. There are three major functions for this category: tag, content_tag and input_tag.

The tag and content_tag are for building arbitrary html tags with a name and specified options. If the tag contains "content" within then content_tag is used. For example:

<%= tag :img, :src => "/my_image.png" %>
  # => <img src='/my_image.png'>

<% content_tag :p, :class => "stuff" do %>
  Hello
<% end %>
  # => <p class='stuff'>Hello</p>

The input_tag is used to build tags that are related to accepting input from the user:

input_tag :text, :class => "demo" 
  # => <input type='text' class='demo'>
input_tag :password, :value => "secret", :class => "demo"
  # => <input type='password' value='secret' class='demo'>

Asset Helpers

Asset helpers are intended to help insert useful html onto a view template such as hyperlinks, mail_to links, images, stylesheets and javascript. An example of their uses would be on a simple view template:

<html>
<head>
  <%= stylesheet_link_tag 'layout' %>
  <%= javascript_include_tag 'application' %>
  <%= favicon_tag 'images/favicon.png' %>
</head>
<body>
  <p><%= link_to 'Blog', '/blog', :class => 'example' %></p>
  <p>Mail me at <%= mail_to 'fake@faker.com', "Fake Email Link", :cc => "test@demo.com" %></p>
  <p><%= image_tag 'padrino.png', :width => '35', :class => 'logo' %></p>
</body>
</html>

You can use auto_stylesheet_link_tag and auto_javascript_include_tag to generate stylesheet and JS includes based on the current path, so if your page is "contact.html", you'll get "contact.css" and "contact.js".

Form Helpers

Form helpers are the "standard" form tag helpers you would come to expect when building forms. A simple example of constructing a non-object form would be:

<% form_tag '/destroy', :class => 'destroy-form', :method => 'delete' do %>
  <% field_set_tag do %>
    <p>
      <%= label_tag :username, :class => 'first' %>
      <%= text_field_tag :username, :value => params[:username] %>
    </p>
    <p>
      <%= label_tag :password, :class => 'first' %>
      <%= password_field_tag :password, :value => params[:password] %>
    </p>
    <p>
      <%= label_tag :strategy %>
      <%= select_tag :strategy, :options => ['delete', 'destroy'],
          :selected => 'delete' %>
    </p>
    <p>
      <%= check_box_tag :confirm_delete %>
    </p>
  <% end %>
  <% field_set_tag(:class => 'buttons') do %>
    <%= submit_tag "Remove" %>
  <% end %>
<% end %>

Format Helpers

Format helpers are several useful utilities for manipulating the format of text to achieve a goal. The four format helpers are escape_html, distance_of_time_in_words, time_ago_in_words, and js_escape_html.

The escape_html and js_escape_html function are for taking an html string and escaping certain characters. escape_html will escape ampersands, brackets and quotes to their HTML/XML entities. This is useful to sanitize user content before displaying this on a template. js_escape_html is used for passing javascript information from a js template to a javascript function.

escape_html('<hello>&<goodbye>') # => &lt;hello&gt;&amp;&lt;goodbye&gt;

There is also an alias for escape_html called h for even easier usage within templates.

Format helpers also includes a number of useful text manipulation functions such as simple_format, pluralize, word_wrap, and truncate.

simple_format("hello\nworld") 
  # => "<p>hello<br/>world</p>"
pluralize(2, 'person') 
  # => '2 people'
word_wrap('Once upon a time', :line_width => 8) 
  # => "Once upon\na time"
truncate("Once upon a time in a world far far away", :length => 8) 
  # => "Once upon..."
truncate_words("Once upon a time in a world far far away", :length => 4)
  # => "Once upon a time..."
highlight('Lorem dolor sit', 'dolor') 
  # => "Lorem <strong class="highlight">dolor</strong> sit"

Lorem Ipsum & Placehold.it helpers

The Frank project, a static tool also inspired by Sinatra, has a wonderful set of helpers for generating random text content and placeholder images. We've adapted this code for Middleman (god bless the MIT license).

For example, if you want to insert 5 sentences of lorem ipsum, you would write

<%= lorem.sentences 5 %>

Other methods available to be used for text:

lorem.sentence      # returns a single sentence
lorem.words 5       # returns 5 individual words
lorem.word
lorem.paragraphs 10 # returns 10 paragraphs 
lorem.paragraph
lorem.date          # accepts a strftime format argument
lorem.name
lorem.first_name
lorem.last_name
lorem.email

And to use placeholder images:

lorem.image('300x400')
  #=> http://placehold.it/300x400
lorem.image('300x400', :background_color => '333', :color => 'fff')
  #=> http://placehold.it/300x400/333/fff
lorem.image('300x400', :random_color => true)
  #=> http://placehold.it/300x400/f47av7/9fbc34d
lorem.image('300x400', :text => 'blah')
  #=> http://placehold.it/300x400&text=blah

Page Classes

It can be useful to generate classes on the body tag that correspond to the site hierarchy. page_classes generates those classes. Imagine you have a page at projects/rockets/saturn-v.html, and the following in your layout:

<body class="<%= page_classes %>">

You'll get:

<body class="projects rockets saturn-v">

This makes it easy to apply project-specific, or rocket-specific styles to the page.

Custom Defined Helpers

In addition to the helpers provided by Middleman out of the box, you can also add your own helper methods and classes that will be accessible within any controller or view automatically.

To define a helper method, use the helpers block in config.rb:

helpers do
  def some_method
    # ...do something here...
  end
end

Alternatively, you can create external Ruby modules which contain helpers and include them. You can put files in the lib directory. For example, if you were to extract the above helpers into a file named lib/custom_helpers.rb, you could create a module:

module CustomHelpers
  def some_method
    # ...do something here...
  end
end

Then in config.rb:

require "lib/custom_helpers"
helpers CustomHelpers

An even easier way is to put your helpers in the helpers directory and name them after their module (i.e., CustomHelpers lives in helpers/custom_helpers.rb). Then, Middleman will automatically load them and register them as helpers.