No commit activity in last 3 years
No release in over 3 years
Small CMS Admin module for Rails



 Project Readme

Cms9 Logo


Gem Version

Small CMS Admin module for developers.

Demo Application running on Cms9.

What Is Cms9?

Cms9 is not standard CMS - it is targeted for developers to ease process of embedding CMS functionality to any site.

Cms9 provides admin dashboard where user can:

  • Define different types of forms (News, BlogPost, Ads, Jobs, ...)
  • Adding user defined fields to forms
  • Currently we are supporting following field types
    • Text field
    • Text Area (WYSIWYG-ed text area using ckedit)
    • Number
    • Choose Single
    • Choose Multiple
    • Date
    • Time
    • Date & Time
    • Image
  • Manage data for each form

Cms9 does not have any functionality regarding displaying content - it is firstly there to provide Admin dashboard where data can be defined and managed. On the other side it exposes simple interface to access that data.


  • Rails 5+
  • Automatic form validation
  • Events history (record actions like create/update/delete on Post Types and their Posts)
  • Authentication customizable (via Devise or similar frameworks)
  • Dragonfly for handling images and other attachments
  • Ckeditor as default WYSIWYG text editor
  • Bootstrap 3+ with Admin LTE template

Getting Started

Add Cms9 to your Gemfile:

# Gemfile
gem "cms9"

Run the installer:

$ rails generate cms9:install [DEF_ROUTE]

Where [DEF_ROUTE] is optional and presents where your Cms9 route will be mounted, by default it's /cms9

Install generator will mount Cms9 route, add current_user configurator initializer and additional configuration for Ckeditor.

Then run:

$ rails db:migrate

Open http://localhost:3000/cms9 to see your new Cms9 dashboard in action.

Managing Content

Content is managed by creating Post Types (aka Post Definitions). Post Type represents form for specific data - in case of news site it can be News Form that have multiple fields for Title, Content, CoverImage, PublishedStatus. Each of those fields can be created from Dashboard.

Once Post Type with specific name is created and all fields are added CMS9 Admin can start creating data (Posts) based on those Post Types.

Cms9 doesn't have any functionality to display content but exposes simple interface to retrieving data. E.g inside News app you can access all Posts with:

<% @Cms9::Post.each do |post| %>
  <%= post.field('Title) %>
<% end %>

You can make any kind of layout for your posts and showed them however you want. Once you made a simple layout, you are ready to create as many posts as you want. It's that easy.

Data Interface

All Data Interface classes are ActveRecord models.

Cms9::PostDefinition - Represents Form Defintion e.g. News, Jobs, Ads, Cms9::PostField - each PostDefinition contains multiple fields that describes type of data Cms9::Post - Represents post with data. Each Post belongs to one of PostDefinitions Cms9::Field - Represents value for each field and belongs to Post


Methods: fields() - returns list of fields that defines PostDefinition field(name) - returns field by name

E.g. If user Created PostDefinition called 'News' with Title and Content fields we can retrieve it by:

Cms9::PostDefinition.all - returns all post definitions Cms9::PostDefinition.all.first.fields() - returns all fields for this Post Type Cms9::PostDefinition.all.first.field('Title') - returns field that describes field named 'Title'


Class represents definition of Post Type field. Each class have 'name' (unique in context of one PostDefintion), 'Type' and extra parameters depending on type. Currently we are supporting following types: Text field, Text Area (WYSIWYG-ed text area using ckedit), Number, Choose Single, Choose Multiple, Date, Time, Date & Time, Image.


field(name) - Returns Cms9::Field by name


Represents value for particular field. Depending on the PostField type 'value' column is serialized differently.

Following helpers can be applied to Cms9::Field for easier data extraction/displaying:



Authorization should be added using the current_user method. If you pass a block it will be triggered through a before filter on first action in Cms9.

To begin with, you may be interested in setting up Devise or something similar.

After, in your User model, you need to implement method cms9_admin? which will be used to recognize users and give them permission to access Cms9 dashboard:

Example of User Model:

class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  def cms9_admin?
    return true     # All users have access to Cms9 dashboard

In config/initializers/cms9_configurator.rb we are passing Devise current_user method (or whatever you use to recognize user) and destroy_user_session_path which is default path for deleting users session (logout):

Cms9.configure do |config|
  config.current_user =  :current_user
  config.destroy_user_session =  :destroy_user_session_path

Note: In Devise, current_user method and destroy_user_session_path are used by default, it will work without passing it to Cms9 configuration. Be sure, if you are using something else, to pass that method and path.


  • Install ImageMagick for Dragonfly's image processing
    • If you will use Dragonfly data stores (which are not included in core of Dragonfly) you need to include them in Gemfile: Amazon S3, Couch or Mongo
    • In case you need data store which is not listed, you can also build a custom data store - Building a custom data store

Dragonfly data stores

By default Dragonfly is using datastore:file. If you plan to use any other data store, after including gem and install you need to override Dragonflys configuration.

For example if you are going to use Amazon S3 as your default data store, you need to make initializer (e.g config/initializers/init_dragonfly_s3.rb)which will override configuration (one for Dragonfly uploader, and second for Ckeditor assets uploader):

require 'dragonfly/s3_data_store' do
  datastore :s3,
    bucket_name: 'mybucket',
    access_key_id: 'my_access_key_id',
    secret_access_key: 'my_secret_access_key'
end do

  datastore :s3,
    bucket_name: 'mybucket',
    access_key_id: 'my_access_key_id',
    secret_access_key: 'my_secret_access_key'



The gem is available as open source under the terms of the MIT License.