This guide is based on Refinery CMS 1.0.8 so some of the code shown here may not work in earlier versions of Refinery.

1 Guide Assumptions

This guide is designed for beginners who want to get started with a Refinery CMS site from scratch. It does not assume that you have any prior experience with Refinery. However, to get the most out of it, you need to have some prerequisites installed:

  • The Ruby language version 1.8.7 or higher (1.9.2 recommended)

Ruby 1.9.1 is not usable because it outright segfaults on Rails 3.0, so if you want to use Rails 3 with 1.9.x jump on 1.9.2 for smooth sailing.

If you don’t already have these things, then you will need to follow the Installing Refinery Prerequisites guide.

It is recommended that developers use RVM to manage Ruby versions and gems. Once RVM is installed on your system, and you’ve created a gemset for the project, create an .rvmrc file in the site’s root directory. Its contents should look something like:

rvm use --create ruby-1.9.2@refinery

Refinery is a Ruby on Rails web application. If you have no prior experience with Rails, you will find a very steep learning curve diving straight into Refinery. There are some good free resources on the Internet for learning Rails, including:

2 What is Refinery CMS?

Refinery CMS, often shortened to Refinery, is an open source content management system written in Ruby as a Ruby on Rails web application with JQuery used as the JavaScript library. Refinery runs on Rails 3.0.

Refinery differs from similar projects by targeting a non-technical end user and allowing the developer to create a flexible website rapidly by staying as close as possible to the conventions of the Ruby on Rails framework.

The Refinery philosophy includes several guiding principles:

  • “The Rails Way” where possible – Refinery embraces conventions used in Rails, allowing any Rails programmer to leverage existing knowledge to get up and running quickly.
  • End user focused interface – Refinery’s user interface is simple, bright and attractive so end users feel invited and not overwhelmed.
  • Awesome developer tools – Refinery makes it easy for developers to add functionality and change the front end look and feel.
  • Encourage and Help Others – Refinery has an active community on Google Groups and IRC. If you ever have a question there is someone able and willing to assist.

2.1 Refinery’s architecture

Refinery comprises of several Rails Engines that sit under /vendor/refinerycms. Each engine acts like a mini Rails application with their own routes and views. Refinery is architected like this so that it keeps out of the way of any custom development you will do in the /app directory.

2.2 Core engines

The engines Refinery comes with are:

  • Authentication – manages users and sessions within Refinery.
  • Core – contains default layouts, views, javascripts and CSS. This engine also has an engine API for extending Refinery and everything Refinery needs to hook into Rails.
  • Dashboard – shows you what’s recently been updated.
  • Images – handles image upload, insertion and processing images using Dragonfly.
  • Pages – allows you to manage pages including the structure of your site displayed in the front end.
  • Resources – handles file upload and storage.
  • Settings – manages various settings you can configure in Refinery.

3 Creating a new Refinery project

If you follow this guide, you’ll create a Refinery site called rickrockstar that will have a custom design and an events engine to allow Rick to tell his fans when his next gig is.

Before you can start building this site, you need to make sure that you have Refinery itself installed.

3.1 Installing Refinery

The easiest way to install Refinery is to take advantage of RubyGems.

# gem install refinerycms

If you’re working on Windows, you should be aware that the vast majority of Refinery development is done in Unix environments. If at all possible, we suggest that you develop on a Linux based operating system.

3.2 Creating a Refinery application

The best way to use this guide is to follow each step as it happens, no code or step needed to make this example application has been left out, so you can literally follow along step by step.

To begin, open a terminal, navigate to a folder where you have rights to create files, and type:

$ refinerycms rickrockstar

This step may take some time to load as it needs to download and install all the ruby gems Refinery depends on.

You can see all of the switches that the refinerycms command accepts by running refinerycms with no options or arguements.

You can run $ refinerycms rickrockstar -r 3.0.9 to generate a refinery stack with any specific version of rails you need.

This will create a new Rails application with Refinery built in called Rick Rock Star in a directory called rickrockstar. It also automatically runs bundle install which will find and install all Refinery’s ruby gem dependencies. Finally, it creates your database and seeds it with some basic defaults to get you started.

In this guide we are using an SQLite3 database for data storage, because it is a zero configuration database that just works. Refinery also supports MySQL and PostgreSQL “out of the box”.

Refinery will create a folder in your working directory called rickrockstar. Switch to this folder:

$ cd rickrockstar

Open up that folder and explore its contents. You’ll notice what you have is a very standard Rails application.

3.3 Running the tests

At your application root:

$ bundle exec rake

This will run cucumber and rspec tests. If tests don’t run, check this guide.

4 Hello, Refinery!

One of the traditional places to start with a new project is by getting some text up on screen quickly, to do this, you need to get your Refinery application server running.

4.1 Starting up the Web Server

You actually have a functional Refinery application already installed. To see it, you need to start a web server on your development machine. You can do this by running:

$ rails server

There is a bug in the current release of Refinery that may cause your database to not be set up properly. If this happens, try running rake db:create and then rake db:migrate.

This will fire up an instance of the WEBrick web server by default. To see your application in action, open a browser window and navigate to http://localhost:3000. You should be greeted with a screen prompting you to create your first Refinery user.

To stop the web server, hit Ctrl+C in the terminal window where it’s running.

If you see this screen it means you have setup everything correctly and your Refinery CMS site is up and running.

4.2 Setting up your first user

Fill out the sign up form to create your first user. This will be the super user of Refinery, meaning this user will be able to create other users later on.

Once you’ve created your first user you’ll see Refinery’s “Dashboard”.

4.3 Setting Your Site Name

The screen above prompts you with a message to set your site name. Click the “go here” link and set the value in the dialog to “Rick Rock Star”. This name will be shown in both the back and front end header as well as the browser title.

Click “Save”

4.4 Explore Refinery

Now you’re setup, click around the various tabs in the backend and become familiar with what comes out of the box.

While exploring one of the first things I do is reorder the tabs to reflect what I will be working on the most. Click the tab with the two green arrows, and then drag the backend tabs, for example “Users” or “Settings”, into an order which makes more sense to you.

Click the reorder button again when you’re done to save.

4.5 Switching to your front end

You’re currently in the back end Refinery site editor. To see your front end site click “Switch to your website”.

As you can see Refinery is already displaying a basic menu and layout ready for you to customise.

If you get a 404 error on the homepage, try running the rake db:seed and then restarting the server:

5 Customising the Design

The layout Refinery provides out of the box is very barebones. We’ll now guide you through customising the front end design to give Rick the beautiful site we promised.

5.1 Overriding your first view

By default Refinery has a range of views built in to display the front end site you currently have. But more times than often you want to customise them with your own layout and design.

Overriding Refinery views is a common pattern which is worth keeping in mind at all times. If Refinery isn’t displaying something how you’d like, just override it.

If you request http://localhost:3000/about this maps by default to Refinery’s pages_controller.rb show action.

So as you would expect the view for this action is located in app/views/pages/show.html.erb. You won’t be able to see this file because Refinery is providing it for you. Next let’s override that view and replace it with our own.

5.2 Overriding your first view

Refinery comes with a rake task called refinery:override which allows you to copy files out of Refinery and into your own application to change. To see a list of possible commands simply run rake refinery:override in the console. Let’s override the pages show view:

$ rake refinery:override view=pages/show
$ Copied view template file to app/views/pages/show.html.erb

Now edit app/views/pages/show.html.erb and it will look like this:

<%= render :partial => "/shared/content_page" %>

Refinery has a content_page partial it uses just to get you started. But we’ll soon remove this and use our own ERB view instead.

5.3 Rendering content using @page

Every view in Refinery has an instance variable called @page available. The best way to explain how this works is just to show you.

Replace the contents of app/views/pages/show.html.erb with this:

<section id='body_content'>
  <%=raw @page.content_for(:body) %>
</section>
<section id='side_body_content'>
  <%=raw @page.content_for(:side_body) %>
</section>

As you can see we’re going to render a view with some HTML5 tags and along with some content coming from the CMS (those are the lines that mention @page).

@page has what we call PageParts associated with it. To see what I mean go to http://localhost:3000/refinery/pages and then click edit on the page titled “About”.

When you edit the about page you’ll see something like this:

You’ll notice two tabs on the page “Body” and “Side Body”. These are Page Parts, or in other words a single piece of content attached to this page that you can render in your view. There is a “Body” tab with some content on this screen, to render that same content in your view you put:

<%=raw @page.content_for(:body) %>

5.4 Styling your views

As mentioned earlier, a key principle in Refinery is to stick to “The Rails Way” where possible. This is apparent in the way you style your views too. You style your site exactly how you would style any Rails application, using public/stylesheets/application.css

Open up public/stylesheets/application.css and add this:

@import url('refinery/application.css');

body {
  background: #DDD;
  font-family: Verdana;
  font-size: 13px;
  line-height: 18px;
}

#body_content, #side_body_content {
  float: left;
  width: 45%;
  background: white;
  color: #333;
  padding: 20px;
}

#menu ul {
  list-style: none;
  padding: 0px;
}

#menu ul li {
  float: left;
  margin-right: 10px;
}

#menu ul li a {
  display: block;
  padding: 5px 10px;
  text-decoration: none;
}

#menu ul li.selected a, #menu ul li a:hover {
  background: #CCC;
}

When on the home page of your site, Refinery automatically loads an extra stylesheet located in public/stylesheets/home.css as often sites have a different style on the home page.

Note that ‘refinery/application.css’ is a stylesheet located in the refinery folder, which is in the refinerycms gem. Without it, front end pages do not include refinery/applications.css by default. Feel free to leave out this import.

Now when you view your front end at http://localhost:3000 you’ll notice your site has a grey background, with a horizontal menu and two white content areas.

5.5 What we just did

We just overwrote the pages/show view and replaced it with our own version. We learnt how to use @page to display content entered in the backend.

Finally we added a (super) simple style that changes the colour of the background and uses our pages/show view to split into two even columns.

6 Extending Refinery with your first Engine

6.1 The Anatomy of an Engine

Think of a Refinery engine as a mini Rails application running in your vendor/engines directory. Each engine specifies its own routes in the config directory and has its own views and controllers in its own app directory. Engines can even serve up their own images, stylesheets and javascripts from the engines public directory.

6.2 Generating an engine

Refinery ships with an engine generator that makes adding your own functionality a breeze. It works just like the Rails scaffold generator.

$ rails generate refinery_engine singular_model_name attribute:type [attribute:type ...]

to see all the options supported by the refinery_engine generator just run rails g refinery_engine

Here is a list of the different field types and what they give you:

field type description
text a multiline visual editor
resource a link which pops open a dialog which allows the user to select an existing file or upload a new one
image a link which pops open a dialog which allows the user to select an existing image or upload a new one
string and integer a standard single line text input

If you remember, we told Rick that we’ll give him an area to post up events he’ll be at. Although he could technically create a new page in Refinery to add this content there, areas that have special functionality are much better suited as an engine.

Rick is going to want to enter the following information about each event:

  • The event title
  • The event date
  • A photo
  • A little blurb about the event.

Run this command to generate the events engine for Rick1:

$ rails generate refinery_engine event title:string date:datetime photo:image blurb:text
      create  vendor/engines/events/app/controllers/admin/events_controller.rb
      create  vendor/engines/events/app/controllers/events_controller.rb
      create  vendor/engines/events/app/models/event.rb
      create  vendor/engines/events/app/views/admin/events/_form.html.erb
      create  vendor/engines/events/app/views/admin/events/_event.html.erb
      create  vendor/engines/events/app/views/admin/events/_sortable_list.html.erb
      create  vendor/engines/events/app/views/admin/events/edit.html.erb
      create  vendor/engines/events/app/views/admin/events/index.html.erb
      create  vendor/engines/events/app/views/admin/events/new.html.erb
      create  vendor/engines/events/app/views/events/index.html.erb
      create  vendor/engines/events/app/views/events/show.html.erb
      create  vendor/engines/events/config/locales/en.yml
      create  vendor/engines/events/config/locales/lolcat.yml
      create  vendor/engines/events/config/locales/nb.yml
      create  vendor/engines/events/config/locales/nl.yml
      create  vendor/engines/events/config/routes.rb
      create  vendor/engines/events/db/migrate/create_events.rb
      create  vendor/engines/events/db/seeds/events.rb
      create  vendor/engines/events/features/manage_events.feature
      create  vendor/engines/events/features/step_definitions/event_steps.rb
      create  vendor/engines/events/features/support/paths.rb
      create  vendor/engines/events/lib/generators/refinerycms_events_generator.rb
      create  vendor/engines/events/lib/events.rb
      create  vendor/engines/events/lib/tasks/events.rake
      create  vendor/engines/events/public/.gitkeep
      create  vendor/engines/events/readme.md
      create  vendor/engines/events/refinerycms-events.gemspec
------------------------
Now run:
bundle install
rails generate refinerycms_events
rake db:migrate
------------------------

As the output shows next run:

$ bundle install
$ rails generate refinerycms_events
$ rake db:migrate

A refinerycms_events generator is created for you to install the migration to create the events table.

When new engines are added it’s a good idea to restart your server for new changes to be loaded in.

Now go to the backend of your Refinery site http://localhost:3000/refinery and you’ll notice a new tab called “Events”. Click on “Add new event” and you’ll see something like this:

You’ll see the entire form has been generated for you based off the field types you specified when generating the events section. The blurb has a visual editor, the date field is a date picker and the photo allows you to pick or upload a new photo from a built in Refinery dialog.

Add a couple of mock events to your events engine.

Now click on “Switch to your website”, and navigate to http://localhost:3000/events

You’ll notice not only has Refinery generated the backend “Events” tab but also a new menu item called “Events” and two new front end views index.html.erb and show.html.erb located in vendor/engines/events/app/events/ for you to customise.

As you can see, Refinery makes it insanely easy to quickly add new engines to manage various areas of a site.

But I’ve noticed one problem. The “2011 Music Awards” is showing up in the middle when it makes more sense to order the events with the latest event at the top. To fix this we need to understand what’s happening under the hood of a Refinery engine. Let’s dive in.

6.3 Crudify: The Backbone of Refinery Engines

Any Refinery engine, even the built-in ones, that focus on Create, Read, Update and Delete are driven by crudify. Crudify is a highly reusable module included with Refinery that gives you all the standard CRUD actions as well as reordering, searching and paging.

Open up vendor/engines/events/app/controllers/admin/events_controller.rb and look at it’s contents:

class Admin::EventsController < Admin::BaseController
  crudify :event
end

Most of the time crudify’s defaults are bang on, but if you need to, you can easily customise how it works2.

But default crudify assumes your records will be sortable. But events are not manually sortable, it makes more sense to order them by their event date. Update the contents of the file to this:

class Admin::EventsController < Admin::BaseController
  crudify :event, :order => "date DESC",
                   :sortable => false
end

This will tell crudify to sort by our event date field and to turn off manual sorting by the user.

Finally edit vendor/engines/events/app/controllers/events_controller.rb and replace the find_all_events method with this one:

class EventsController < ApplicationController

  # code

protected

  def find_all_events
    # Order by event date
    @events = Event.order("date DESC")
  end

  # code

end

Now when you look at http://localhost:3000/events you’ll notice they’re now being sorted by the event date.

7 What’s Next?

Now that you’ve made your first Refinery application with a custom events engine, you should feel free to update it and experiment on your own. But you don’t have to do everything without help.

If you need assistance getting up and running with Refinery follow the How to get help with Refinery Guide and for professional support & consulting contact Resolve Digital (the creators of Refinery).

1 If you want to know more about the Engine’s file structure, check out the separate documentation on Engines.

2 There’s a separate doc on configuring and overriding Crudify.