Using a partial as an optional layout

Rails uses partials a lot, and you can even use partials as mini-layouts. What I wanted to do is render flashes either as a normal partial (i.e. passing a string of text to be displayed), or as a layout (passing a block of markup to be rendered).

The idea

I’m using Twitter’s Bootstrap CSS message-box to style my flashes, and I wanted to extract the common functionality to be able to call (e.g.) an error message box like this using a block to be rendered:


= render layout: "common/alerts/alert_message_box", locals: { type: :error } do
= error_messages_for @customer

But I also wanted the option to pass basic text and have it displayed within the message-box, like so


= render "common/alerts/alert_message_box", content: "You've got errors"

Extracting Bootstrap message-boxes

I simply created a partial with this code:


- options ||= {}
- options[:class] = Array(options[:class]) << "alert-message block-message fade in #{type}"
- options&#91;:class&#93; = options&#91;:class&#93;.join(' ')
%div{ options.merge({'data-alert' => 'alert'}) }
= link_to 'x', '#', :class => 'close'
- if defined?(content)
= content
- else
= yield

Besides the markup needed for the message-box functionality (adding a close link, setting a ‘data-alert’ HTML attribute, etc.), you can see that I simply check if a `content` value was passed to the partial. If that’s the case, we simply want to display that. Otherwise, we yield to the block that has been passed and the block’s content will be rendered within the message-box.

Pretty straightforward, but cuts down a lot on non-DRY code…

This entry was posted in Rails. Bookmark the permalink.