Refinery CMS - Implementing a Template / Design

Posted by Gant on June 20th, 2012

Lots of Rails developers may find themselves implementing a custom template. It's easy enough with the Rails framework, but there's a small amount of extra know how that's needed in order to implement your template with an existing Content Management system. Each CMS requires you work with it various regards. Today we're covering Refinery CMS. This blog post assumes a moderate amount of Rails and web knowledge.

What is Refinery?

RefineryIf you have no idea what refinery is, it's a CMS built in Ruby on Rails for creating custom content manageable websites. The design of the CMS is to try to implement as much Rails mentality as possible, so you receive the full benefit of the framework. It's open source, constantly updated, extendable, and popular.

Getting Started

If at all possible, before you get started with styling or creating the original template, try to use the same ids and class names that are provided by default in Refinery. This might save you a lot of time and effort since the wonderful team at Resolve Digital has already likely identified the element for you. There are even courtesy classes like "first" and "last" on menu elements, which make advanced styling techniques easy.

If it's too late, or you simply had no say in the template creation process, there's likely a one to one mapping of identifier elements that should allow you to catch up with minimal effort. Just implement some base content and take note of the tags that are created for you. Your simplest solution is to convert your CSS to use these new tags, and then simply import your new CSS into the Rails project.

The plethora of ids and classes handles a majority of your template needs, but not all of them. Let's say you want to style or add something that doesn't come in the core Refinery system. You literally will need to inject extra content into the base system and for situations like this, we use overrides.


Fortunately, any aspect of Refinery can be overridden. Any controller, model, or view can be converted from being handled by refinery to being handled by you!

BarrelWhen you take control away from the refinery project with an override, you should do so with the understanding that you're now the maintainer of that code. In this aspect, it is possible to create a situation where you override a component, then update Refinery but don't see the update in your project because your overriden code will stay the same. With this knowledge, you should strive to override as little as possible so that you can continue to leverage upstream improvements from the Refinery engine or plugins with minimal maintenance effort.

Views are the easiest and safest aspects to override, since they're innately something you should be managing in any project. Moderation can still be used with views, however, but page header, footer, menu etc likely candidates for designing your custom template. To override you simply invoke the refinery override rake task, and then tell it what you'd like. The following are likely some commands you'll run with any Refinery install.

1rake refinery:override view=refinery/_header
2rake refinery:override view=refinery/_menu
3rake refinery:override view=refinery/_footer
4rake refinery:override view=refinery/pages/show
5rake refinery:override view=refinery/pages/home

The first three lines give you access to partial views, the second are to actual pages. You may ask, "How the hell did you know what to put in the override parameter to get those items?" Unfortunately the honest answer is that you have to poke around the source code of Refinery and identify what aspects you're looking to override. Fortunately, the above examples are some of the most common, and as well as most of what you need is usually found in the refinery folder (like all of the above). And as with anything, the more you work with it, the more you'll be able to identify the partials you're looking for.

Caveat of home and show

In modern design patterns of most current websites, there are usually aspects that are "Front Page Only", and all ancillary pages follow a completely different structure. Following this practice, you'll notice refinery comes ready to handle this out the box. That's why two pages were overridden in the above examples. As you can see, there are different page views for the front page (i.e. home) and all others (show). It's good to know this is already in place, or it might cause some headache for a beginner trying to implement, or remove it.

If this is something you're not interested in, you could simply call render inside of one, to call the other in your override.

Refinery Plugins (aka Engines, aka Extensions) in your Template

Lastly, there's a great selection of plugin engines that are available to you in Refinery. There's plenty of information on them provided in the Additional Reading section of this post. Using the same mentality you use for Refinery, you can directly apply your rational to the plugins. Let's say you decided to implement the site search engine. Now if you're looking to show the search functionality in your _header partial view (likely), you can reference the partial directly without overriding it. So an example header might look like this:

 1<header id="logo">
 2  <%= render(:partial => "/refinery/shared/search") %>
 3  <p>555-555-5555</p>
 5<%= render(:partial => "/refinery/menu", :locals => {
 6  :dom_id => 'menu',
 7  :css => 'menu'
 8  }) 

Notice that the engine partial view was located in the sub-folder "shared". Browsing the source of your included engine will usually give you a good idea of what partial views you can render.

That's about it

We went over making your code conform to Refinery, and making Refinery conform to your code. We even covered a few pitfalls, suggestions and an engine. That's about everything you'll need for Implementing a template in Refinery. If you're interested in Refinery interaction, engine creation, or some other aspect, please leave a comment and we'll seriously consider writing a blog post on the topic.

Additional Reading:

Copyright ©2015 Iconoclast Labs LLC