![]() |
Resolve Digital, a Rails consulting firm with offices in California and New Zealand. created Refinery CMS back in 2004 and is the Technical Partner atDavid also co-founded RefineryHQ.com, a fully hosted version of Refinery that allows you to create a site, customise your design and enter content all from your browser. |
Back in 2004 there weren't any suitable Rails CMS options, so I created my own. Building site after site, I eventually started to combine the common elements into a project called mTools.
mTools was closed source for 5 years before being renamed to Refinery CMS and released as open source in mid 2009.
On August 29th, 2010 — two days after Rails 3 was released, Refinery announced full Rails 3 support, making it the first popular CMS to support Rails 3.
At Resolve Digital we've now built over 70 sites using Refinery and every time we sit down with the end user we gather feedback and make it easier for them to use. It's this feedback which has made Refinery different from other CMS options available.
But the end user experience is only half the story. To have a truly fantastic CMS, it needs to be a delight to the programmer.
Refinery is based off a few key 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.
What do you get out of the box?
- Page management
Manage site structure. Edit content using a WYSIWYG editor. - Image and file management
Upload and insert images. Store and manage files. Use local storage or Amazon's S3. - Contact form & inquiry management
Collect and manage inquiries from a contact form. Automatically filters spam. - User management
Set up multiple users and manage which areas they can access. - Plugins
Extend Refinery by creating Rails style engines using the engine generator. - Settings
Manage site settings such as your site name and Google Analytics tracking code. - I18n Translations
English, Danish, German, Spanish, French, Italian, Dutch, Norwegian Bokmål, Portuguese and Slovenian.
Installation
First you'll need to install the bundler and refinerycms gems:
gem install bundler
gem install refinerycms
Next create your Refinery project. This will create your database, install any required gems and set up a standard Rails app with Refinery included:
refinerycms path/to/project
Note this will by default setup your application with a SQLite database. The refinerycms command also supports --database which allows you to specify mysql, postgresql or sqlite3. Here's an example of Refinery being setup with MySQL
refinerycms path/to/project --database mysql
Finally, start your web server:
cd path/to/project
rails server
Visit: http://localhost:3000 in your browser to set up your first Refinery user.
Having Problems? Watch the "How to Install Refinery" screencast (http://tutorials.refinerycms.org/tutorials/how-to-install-refinery).
Just want to have a play? Check out the demo site at http://demo.refinerycms.com/refinery
Extending Refinery with Engines
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 ...]
Example: Products Engine
In this example, we're going to generate a new engine that will let us manage products. Each product will have a title, description, image and downloadable brochure. To create this new engine, at your application root run:
rails generate refinery_engine product title:string
description:text image:image brochure:resource
bundle install
rake db:migrate
Finally, restart your web server if it is already running.
This single command will generate a new engine located at vendor/engines/products with all of the necessary backend views and some basic front end views. It even makes a customised form for adding and editing products, based on the field types specified which looks like this:
You can see that out of the box a new tab called "Products" has been added for the end user to manage their products. Multiline text fields automatically use the visual editor.
Refinery Plugin Generator Field Types
- text - multiline text area with a visual editor
- image - link to an image picker dialogue
- resource - link to a resource picker dialogue
- string and integer - standard one line input box
- datetime, date and time - standard time and date drop downs
Now that our products engine is up and running, let's go a little deeper to see how an engine actually works.
The Anatomy of a Refinery 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.
products
|- app
| |- controllers
| | |- admin
| | | |- products_controller.rb
| | |- products_controller.rb
| |- models
| | |- product.rb
| |- views
| |- products
| | |- index.html.erb
| | |- show.html.erb
| |- admin
| |- products
| |- _form.html.erb
| |- _product.html.erb
| |- _sortable_list.html.erb
| |- edit.html.erb
| |- index.html.erb
| |- new.html.erb
|- config
| |- routes.rb
| |- locales
| |- en.yml
|- lib
|- products.rb
Engines That Come With Refinery
The Refinery project itself is actually broken up into 7 engines:
- authentication
- core
- dashboard
- images
- pages
- resources
- settings
Each of these Refinery engines are very similar to the product engine above.
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.
If we take our products engine and look at the Admin::ProductsController. It looks like:
class Admin::ProductsController < ApplicationController
crudify :products
end
Most of the time crudify's defaults are bang on, but if you need to, you can easily customise how it works.
Let's just say we wanted to create a news engine. We'll want to order by date not position. We'll want to add the ability to make draft posts and they won't be sortable because they will order by date. Here's how you'd specify that:
class NewsItemsController < ApplicationController
crudify :news_item, :order => "created_at DESC",
:conditions => 'draft = false',
:sortable => false
end
Customising The Front End
One of Refinery's key principles is 'The Rails Way' where possible. This means as a Rails developer, Refinery tries to use every bit of knowledge you already have.
This principle is apparent with how you customise the front end. To do this you use regular ERB views in app/views, exactly how you would customise the front end of any Rails applicaiton.
Customising How Pages Are Displayed
When a Page is rendered in Refinery, the @page variable is available to use in your view.
Pages have what's called "Page Parts". A "Page Part" is a single piece of content linked to this page. By default pages come with two page parts, "Body" and "Side Body". You can easily add more parts if you need to all pages by default of individual pages (follow this tutorial for instructions: http://tutorials.refinerycms.org/tutorials/how-to-change-the-default-and-individual-page-parts)
Here's an example of pages/show.html.erb using the @page instance variable and rendering its body and side_body content:
app/views/pages/show.html.erb
<div id='body_content'>
<h1 id='body_content_page_title'>
<%= @page.title %>
</h1>
<div id='body_content_left'>
<%= @page[:body] %>
</div>
<div id='body_content_right'>
<%= render :partial => "/shared/random_fact" %>
<%= @page[:side_body] %>
</div>
</div>
Using the two page parts like this is quite common so Refinery provides you with a partial called content_page which gives you the same basic view. This partial is usually all you need. With content_page the view above can be replaced with:
app/views/pages/show.html.erb using content_page partial
<% content_for :body_content_right do %>
<%= render :partial => "/shared/random_fact" %>
<%= @page[:side_body] %>
<% end %>
<%= render :partial => "/shared/content_page" %>
You can use content_for :body_content_right or :body_content_left to customise what goes into those sections. In this case we only need to set the right body content because it's the only non-standard item in the view above.
Tips and Tricks
Updating to the Latest Version of Refinery
Commits to Refinery occur daily and minor releases often come out weekly so keeping your app up to date is very beneficial. Updates provide new features and bug fixes and are usually safe to use as we strive to maintain backward compatibility.
Updating your existing Refinery application is easy. First edit your Gemfile to reflect the latest version of Refinery (the latest version number can be found at rubygems.org/gems/refinerycms):
Gemfile
gem 'refinerycms', '= 0.9.8'
Next run bundler to install this new version
bundle install
And finally run the Refinery update rake task to pull in the latest migrations
rake refinery:update
Setting Up Google Analytics
Default Refinery layouts have Google Analytics support built in. To start using Google Analytics on your site all you need to do is go into the "Settings" area and edit the setting called "Analytics Page Code". Replace "UA-XXXXXX-X" with your Google Analytics code to get up and running.
Deploying on Heroku
First follow the Refinery installation instructions above. Next go to http://heroku.com/ and click "sign up" for a free account.
Now you've got a Heroku account, install the Heroku gem and provide your account credentials:
gem install heroku
heroku list
Now it's time to create your Refinery application using the built in --heroku option
refinerycms myapp --heroku
Watch the output for these lines
Creating Heroku app..
Running: cd /path/to/app/myapp && heroku create
Creating random-site-name..... done
Created http://random-site-name.heroku.com/
This will output the URL for your Heroku hosted Refinery application. Your application should now be live at http://random-site-name.heroku.com
Adding Amazon S3 Support
Create a bucket called my_app_production and uncomment this line in your Gemfile:
gem 'aws-s3'
Next tell Heroku about your new S3 bucket.
heroku config:add S3_KEY=123key S3_SECRET=456secret S3_BUCKET=my_app_production
That's it! Heroku will restart your site and it should be live with S3 support.
Not working? Read the detailed tutorial: http://tutorials.refinerycms.org/tutorials/how-to-install-refinery-on-heroku
Generate Thumbnails On The Fly
image_fu is a built in helper that allows you to instantly create thumbnails out of any image saved in Refinery. Refinery uses Dragonfly (github.com/markevans/dragonfly) which is an on the fly image server that serves an image up in any size you request and then aggressively caches it.
image_fu also cleverly outputs the image dimensions on the image tag to decrease browser rendering time and prevent the page from "jumping" while loading.
Thumbnail Examples
Scale this product image to fit inside a 500x500 box but maintain the proportions.
<%= image_fu(@product.image, "500x500") %>
#=> <img src='/path/to/image/beanie_front.jpg' width='500' height='400'/>
Scale and crop this product image to be exactly 400x300 pixels but maintain the proportions.
<%= image_fu(@product.image, "400x300#c") %>
#=> <img src='/path/to/image/beanie_front.jpg' width='400' height='300'/>
Scale to exactly 200x200, skewing the proportions.
<%= image_fu(@product.image, "200x200!") %>
#=> <img src='/path/to/image/beanie_front.jpg' width='200' height='200'/>
Summary and the Future
Refinery is a great option for content managing your next Rails site. It supports Rails 3, it's backed by Resolve Digital (http://resolvedigital.com) and has a thriving community that continuously improves the project.
It is currently at version 0.9.8 and will be releasing version 1.0 later this year. Be sure to go to http://github.com/resolve/refinerycms and click "watch".