Comfortable Mexican Sofa (CMS)
What is this?
ComfortableMexicanSofa is a micro CMS implemented as a Rails 3.* engine. This CMS is not a full-blown application like RadiantCMS. It's more like the ComatoseCMS, only more modern and infinitely more powerful and flexible. ComfortableMexicanSofa can function as a stand-alone installation, but it's designed to be used as an extension to your Rails application. If you have any (static) content that needs to be managed this CMS will handle it.
This CMS also allows high level of integration. You can easily use page content anywhere within your app, and even use page content as renderable templates from inside your controllers. You may also reuse CMS's admin interface for your own admin backend.
Installation
Add gem definition to your Gemfile:
config.gem 'comfortable_mexican_sofa'
Then from the Rails project's root run:
bundle install
rails g cms
rake db:migrate
At this point you should have database structure created, some assets copied to /public directory and initializer set up.
Usage
Now you should be able to navigate to http://yoursite/cms-admin
Step 1: Create Layout
Before creating pages and populating them with content we need to create a layout. Layout is the template of your pages. It defines some reusable content (like header and footer, for example) and places where the content goes. A very simple layout can look like this:
<html>
<body>
<h1>My Awesome Site</h1>
{{ cms:page:content }}
</body>
</html>
So there's your layout and the {{cms:page:content}}
defines a place where renderable content
will go. There's just a handful of tags that you can use.
Layout may also be linked to the application layout
. As a result cms page content will end up inside <%= yeild %>
of your application layout.
Page Blocks
pieces of content that will be output on the page:
{{ cms:page:some_label:text }} # will render a text area during page creation
# alternatively you may use: {{ cms:page:some_label }}
{{ cms:page:some_label:string }} # will render a text field during page creation
{{ cms:page:some_label:datetime }} # datetime select widget
{{ cms:page:some_label:integer }} # a number field
Page Fields
pieces of content that are not rendered. They are useful for hidden values you want to use inside your app. @cms_page
instance variable is available when you need to access field values.
{{ cms:field:some_label:text }} # text area for the page creation form
{{ cms:field:some_label:string }} # same as {{ cms:field:some_label }}, this is a text field
{{ cms:field:some_label:datetime }} # datetime
{{ cms:field:some_label:integer }} # a number field
Snippets
bits of reusable content that can be used in pages and layouts
{{ cms:snippet:snippet_slug }}
Helpers
are tags that map to your view helpers methods
{{ cms:helper:method_name }} # gets translated to <%= method_name( ) %>
{{ cms:helper:method_name:x:y:z }} # gets translated to <%= method_name('x', 'y', 'z') %>
Partials
are exactly that. You don't want to do IRB inside CMS so there's a handy tag:
{{ cms:partial:path/to/partial }} # gets translated to <%= render :partial => 'path/to/partial' %>
{{ cms:partial:path/to/partial:x:y }} # gets translated to <%= render :partial => 'path/to/partial',
# :locals => { :param_1 => 'x', :param_2 => 'y'} %>
Step 2: Create Page
Now you're ready to create a page. Based on how you defined your layout, you should have form inputs ready to be populated. Save a page, and it will be accessible from the public side.
Integrating CMS with your app
Unlike most CMS solutions, Sofa is here only to help. Your application is more important. There are few useful ways you can use CMS functionality from your application.
- When CMS renders a page, you automatically have access to
@cms_page
variable. - CMS can take over the rendering of views for your application. For example, http://your-app.local/books hits books_controller#index and if you don't have a view setup CMS will try to serve a page with '/books' path. You can even force your controller to render a particular page like this:
render :cms_page => '/books'
Working with fixtures
During development it's often more convenient to work with files that can be source controlled, versus putting content in the database and then manage database dump. Thankfully Sofa makes working with fixtures easy.
Setting up Fixtures
First of all you need to set a path where fixture files will be found:
# in config/initializers/comfortable_mexican_sofa.rb
if Rails.env.development? || Rails.env.test?
ComfortableMexicanSofa.config.seed_data_path = File.('db/cms_seeds', Rails.root)
end
This is an example of the file/folder structure for fixtures:
your-site.local/
- layouts/
- default_layout.yml
- pages
- index.yml
- help.yml
- help/
- more_help.yml
- snippets
- random_snippet.yml
Then it's a matter of populating the content. Few rules to remember:
- root page is always index.yml
- sections of the page are defined by cms_block_attributes
- parent pages are identified by full_path (slug for layouts)
- folder structure reflects tree structure of the site
Example fixture files for a layout, page and snippet
Note: If ComfortableMexicanSofa.config.seed_data_path is set no content is loaded from database. Only fixture files are used.
Importing fixtures into database
Now that you have all those fixture files, how do we get them into database? Easy:
rake comfortable_mexican_sofa:import:all FROM=your-site.local TO=your-site.com SEED_PATH=/path/to/fixtures
PATH is optional if seed_data_path configuration option is set.
Exporting database data into fixtures
If you need to pull down database content into fixtures it's done as follows:
rake comfortable_mexican_sofa:export:all FROM=your-site.com TO=your-site.local SEED_PATH=/path/to/fixtures
During import/export it will prompt you if there are any files/database entries that are going to be overwritten
Admin Area Integration
Sofa has a wonderful admin area. Why would you want to make your own layout, styling and so on if you can reuse what CMS has.
You can easily make your controllers use layouts and CMS authentication like this:
class Admin::UsersController < CmsAdmin::BaseController
# ...
end
To add your own tabs to the admin area you can use hooks:
# in config/initializers/comfortable_mexican_sofa.rb
ComfortableMexicanSofa::ViewHooks.add(:navigation, '/path/to/view/partial')
ComfortableMexicanSofa::ViewHooks.add(:html_head, '/path/to/view/partial')