A Simple Rails CMS
If you’re building a website, you’re no doubt going to want to add some dynamic content to it. In Ruby on Rails, this is a surprisingly easy task and can be set up in just a few minutes. No gems required.
To get started, first set up a Contents
model:
rails g contents slug:string format:string title:string author:string body:text
Then modify the migration file that was created so it includes a default value
for :format
and has a unique index for :slug
:
1 # File: db/migrate/*_create_contents.rb
2
3 class CreateContents < ActiveRecord::Migration
4 def change
5 create_table :contents do |t|
6 t.string :slug
7 t.string :format, default: "html"
8 t.string :title
9 t.string :author
10 t.text :body
11 t.timestamps
12 end
13
14 add_index :contents, :slug, unique: true
15 end
16 end
Now configure the Content
model so it parameterizes the title into a slug,
which is what we’ll be using for the URL to display the content. You’ll also
need to set up the accessible fields, and validations:
1 # File: app/models/content.rb
2
3 class Content < ActiveRecord::Base
4 attr_accessible :title,
5 :body,
6 :author,
7 :format
8
9 validates_presence_of :title,
10 :format,
11 :slug
12
13 before_validation do
14 self.slug = self.title.parameterize
15 end
16
17 def to_param
18 self.slug
19 end
20 end
Next create a controller that will render the requested Content
:
1 # File: app/controllers/contents_controller.rb
2
3 class ContentsController < ApplicationController
4 def show
5 # Get the ID of the page being requested, defaulting to 'home'
6 @id = params.fetch(:id, 'home')
7
8 # Get the format of the requested content
9 @format = params.fetch(:format, 'html')
10
11 # Find the content by its slug and format
12 @content = Content.find_by_slug_and_format!(@id, @format)
13
14 # Render the content inline
15 render inline: @content.body
16 end
17 end
Configure your app’s routes:
1 # File: config/routes.rb
2
3 MyApp::Application.routes.draw do
4 root to: "contents#show"
5 get "contents/*id" => "contents#show"
6 end
Fire up the rails console
and create some default content:
1 Content.create! format: 'html', title: 'Home Page', body: '<h1><%= @content.title %></h1>'
Now when you visit your app in the browser you’ll be presented with content that was pulled from the database and rendered by your application.
This is just a very brief example of how to set this up. There’s a lot more to take into consideration. For example, since you can execute ERB code in your site’s dynamic content using this method, you’ll need to take the necessary security measures in the controller to ensure that malicious code or rouge scripts could not be executed. Which means that, unless you are the only person who will be editing your site’s content, you will probably want to use something other than Rails default template renderer, such as Shopify’s Liquid template language, since it leaves your site open to too many vulnerabilities otherwise.
You’ll also need to set up the controller to edit the content from within the browser. I left that out of the above example for the sake of brevity, since it is very basic Rails code.