MTJ Hax

Comatose CMS for Ruby on Rails

Posted in ruby on rails by mtjhax on December 20, 2009

Anyone who has built a Rails app and wanted to use a CMS just for the static portions of the site knows that there is no easy solution, especially when the CMS and Rails app need to share things like user logins. This issue is well-described by Aaron Longwell in his June ’09 blog post, The Ruby on Rails CMS Dilemma.

I started playing with different Ruby on Rails CMS offerings to learn more and try to come up with some new approaches. One really interesting little project popped up called Comatose CMS, initially developed by cartoonist/programmer Matt McCray. Comatose has a couple of sweet features I feel like every CMS should have:

  • Comatose runs as a loosely-coupled plugin to your Rails app (as opposed to being the base upon which you need to layer your app). If you want Comatose to generate a page, you just route the request to Comatose with some entries in your routes.rb file. If you want your app to handle the request, route it normally. Simple!
  • Comatose pages can be rendered inline similar to Rails partials. Imagine you have an entire app already built and you need a quick way to allow someone to edit specific chunks of content without moving entire pages into your CMS. Comatose inline rendering could have you there literally in minutes.
  • Comatose can use the same layouts as your regular app.
  • Comatose uses a simple callback pattern to use your app’s authentication and access control as its own. You can configure Comatose to mix-in any modules it needs (like the restful-authentication lib), then set up callback procs to control access to both the generated pages and the back-end editing interface.

I guess the main drawback to Comatose is that the original author has not worked on it recently and the two or three other committers have not made any changes in nearly a year. It does work with the latest Rails 2.x though. With more activity you might see better documentation, more examples and design patterns, maybe a few new features. Also, with a project this inactive, one worries that there are security flaws, performance issues, or other difficulties yet to be discovered. Unless I find another CMS with similar features, I’m thinking of giving it a go in a real project and seeing what I run into.

 

UPDATE October 2010: I realized that there is one major drawback to working with this CMS at this point — it was written to use an older, obsolete version of the Liquid markup language that is embedded into the app. If you install a more recent version of the Liquid GEM for any reason (I tried 2.0.0 and 2.2.2) it will cause Comatose to crash. Of course, someone with a little more free time than I have could fork the Comatose project and update it to use the latest version of Liquid, but this project is looking pretty dead. I guess full-fledged CMS apps like Radiant have officially won the day. Shame there isn’t more interest in this type of hybrid solution.

 

Here are a few Comatose CMS tips:

 

By arranging your routes in different ways, you can have Comatose handle everything, only specific pages, or any page not otherwise explicitly routed. I prefer that last style — just use resource maps and named routes for everything in your app, remove the default :controller/:action/:id routes, and add something like map.comatose_root "" at the end. For example:

map.resources :users
map.resource :profile
map.comatose_admin
map.comatose_root '', :layout => 'application'

A request for anything except /users or /profile will fall through to the CMS. If the CMS cannot find the request page it will render it’s own “404 not found” page (which you define by creating a page called “404” at the top level of your page heirarchy).

 


 

Comatose routes can be used like named routes in the app. For example, one might link to an /about page with comatose_root_path(:about). Sub-pages in the heirarchy can be accessed one of two ways, with an array of strings or symbols, or a string argument to the helper: comatose_root_path([:legal, :privacy]), or comatose_root_path('legal/privacy').

 


 

If you don’t like the look of comatose_root_path(:about) and comatose_root_url(:about) as helpers, you can make a shorter route such as:

map.static ':page', :controller => 'comatose', :action => 'show'

Then use static_path(:about) and static_url(:about) instead. The only drawback to this approach is that sub-pages will end up with ‘%2F’ (the entity for ‘/’) in your browser’s address bar.

To cause errors to be generated instead of 404 pages (maybe useful for debugging during development?) you could limit the possible values for :page as follows:

map.static ':page', :controller => 'comatose', :action => 'show', :page => /about|help|contact|legal\/privacy|legal\/terms/

 


 

For Comatose to use your app’s layouts, any helpers or modules used by the layout need to be included in the Comatose controller since it doesn’t inherit ApplicationController. This is easily configured in environment.rb:

Comatose.configure do |config|
config.helpers << :layout_helper    # my layout helpers
config.includes << :current_user  # my module that includes a current_user method

 


 

Finally, here’s some code for a layout that provides an “Edit this page” link for anyone who is logged in as an administrator:

<% if current_user && current_user.is_admin? && @page && @page.is_a?(Comatose::PageWrapper) %>
<%= link_to("Edit this page", "/comatose_admin/edit/#{@page['id']}") %>
<% end %>

Notice that @page is defined in the layout when Comatose is handling a page. It contains all sorts of useful information to take advantage of in your layout.

Advertisements
Tagged with: , , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: