Skip to content
A simple Rails plugin that brings basic CMS functionality to any app. Just drop it in and go.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.


Tandem CMS

Tandem is a content management system (CMS) for Rails 3.1+. We felt like it was needed because too many of the CMS options for Rails are either unpolished—something we wouldn't want to put in front of our clients or bloated and heavy, causing many headaches when trying to integrate into existing applications.

Tandem was designed to be as simple as can be to integrate into a larger application. It's a mountable engine that allows you to easily specify how it fits into a larger application and doesn't bring any opinions about how that application is architected.

The simplicity doesn't stop there, though. It also has the end user in mind. Through in-place editing, users simply navigate their site like they normally would. If they want to edit something, they simply click on it, edit it, and go on their merry way.

It's early in the life of Tandem and we have lots in store, but it's something we find useful and hope you will too.

Getting Started / Installation

Has it ever been easier to check off that “CMS functionality” feature story?

This assumes you have a rails app already. If you don't, rails new tandem_app

  1. Add the tandem gem to your Gemfile

    gem 'tandem'
  2. Install the gem

    bundle install
  3. Generate the tandem files

    rails g tandem
  4. Migrate

    rake db:migrate
  5. Start your app and you're ready to go.

    rails s


Upgrade just like you would any other engine.

  1. Update the gem version to the latest version in your gemfile if you specify a version.

    gem 'tandem', '~> 0.2'
  2. Install the updated gem

    bundle update tandem
  3. Copy any new migrations from tandem

    rake tandem:install:migrations
  4. Migrate

    rake db:migrate
  5. Enjoy the new tandem goodness.

    rails s


By default, Tandem uses your application layout and Tandem's pages/show template to render pages. Both of these can be customized for an individual page.

Custom pages

With Tandem, you can easily insert editable content into your page by using the simple helpers, tandem_text_tag and tandem_image_tag.

Simply insert those into your templates where you want the user to be able to edit content and Tandem will take care of the rest.

<div id="sidebar">
  <%= tandem_image_tag(:sidebar_image)
  <%= tandem_text_tag(:sidebar_text)

The tandem_text_tag defaults to a basic text area. If you'd like to offer a WYSIWYG editor, you can set the editor option to :wysiwyg:

<%= tandem_text_tag(:sidebar_text, editor: :wysiwyg) %>


Tandem comes with a helper method to add a navigation menu. It's not included in the default views, since it will most likely be used in your app's application layout. Adding it is easy, though.

<%= tandem_navigation_tag(@page) %>

By default, Tandem will produce a nested tree of all your pages. If you just want the top level:

<%= tandem_navigation_tag(@page, Tandem::Page.top_level) %>

If you want to show just the subnavication for a given page:

<%= tandem_navigation_tag(@page, @page.children) %>

You can also create submenus easily by passing in a custom collection of pages, e.g.

<%= tandem_navigation_tag(@page, Tandem::Page.find_by_title('Services').children) %>


Now, most apps don't simply want to let anyone edit content. Tandem allows you to easily specify how it should control access.

Inside config/initializers/tandem.rb, you can define procs for Tandem to use for authentication and authorization.

  1. Tell Tandem how to find the current_user

    Tandem::Configuration.current_user_proc { |request|
      User.find(request.session['user_id']) unless request.session['user_id'].blank?
  2. Define what each user can do using CanCan

    Tandem::Configuration.user_abilities_proc { |user|
      user ||= # guest user (not logged in)
      if user.admin?
        can :manage, :all
        can :read, :all

Paperclip configuration

Tandem uses paperclip for file uploads. If your application needs to modify its settings, simply set the Tandem::Configuration.paperclip_options in /config/initializers/tandem.rb

For example, to store images on S3, add the aws-sdk gem to your Gemfile and set paperclip_options to:

Tandem::Configuration.paperclip_options = { :styles => { :thumb => "150x150>" },
                                            :storage => :s3,
                                            :bucket => { Rails.application.engine_name.gsub(/application$/, Rails.env) },
                                            :s3_credentials => {
                                                                 :access_key_id => ENV['S3_KEY'],
                                                                 :secret_access_key => ENV['S3_SECRET']
                                            } }

Other Options

By default, Tandem mounts to the root of your application. We're not trying to be pushy, it's just what we find ourselves doing 90% of the time. To change this, simply modify your config/routes.rb to something like:

mount Tandem::Engine => "/tandem"

To change the url that you wish to serve unauthorized access errors supply a value to:


By default, the tandem generator copies all tandem layouts to app/views/layouts/tandem. If you wish to move your layouts to another location, supply a value to:


By default, the uploaded images directly in the asset pipeline at :rails_root/public. To change this location, supply a value to:


By default, the uploaded images are stored and accessed via the default “paperclip” conventions (see paperclip gem). To change this behavior, supply a value to:



Every new Tandem default page created has pre-defined classes setup to use either Bootstrap or

Here's a preview of what the html looks like:

  p#notice = notice
    = tandem_image_tag(@page, :default_image)
    = tandem_text_tag(@page, :tandem_text_block)
    = tandem_text_tag(@page, :tandem_sidebar)

If either of those grid systems are being used those styles will pull in accordingly.

Tandem Resources

Tandem realized that even the most basic site will often have pages that should be represented as resources with basic CRUD functionality, e.g. people, events, FAQs, etc. Tandem, therefore, comes with a generator that allows you to create a Tandem resource that provides all of that functionality wrapped in the same Tandem interface your users are used to using for editing other content in the application.

To generate a tandem resource, simply call the tandem_resource generator:

rails generate tandem:resource Faq question:string answer:string position:integer


  1. Fork it.

  2. Create a branch (git checkout -b my_markup)

  3. Commit your changes (git commit -am “Added Snarkdown”)

  4. Push to the branch (git push origin my_markup)

  5. Open a Pull Request

We are big believers in testing, so every pull request needs to be tested.

Running the tests

  1. Run Bundle

    bundle install
  2. Create the Database

    rake db:create
  3. Run the Migrations

    rake db:migrate
  4. Prepare the Test Database

    rake app:db:test:prepare
  5. See all the Green.



Tandem is released under the MIT license:

You can’t perform that action at this time.