Ruby on Rails is an excellent framework for building web applications. Perhaps the best. But it's not currently very well suited to what I call web sites.
The difference is simple. In a web site, the unique business value comes from the content creators (authors, bloggers, photographers, etc). In a web application, the business value comes directly from the programmers. Twitter, Google, Basecamp and eBay are web applications. CBSSports.com, KentuckyDerby.com, corporate brand sites and original news sources are all web sites.
For these projects where it's the content that matters, there's no reason to spend time hand-coding models, controllers, views and test code for things called Pages, Articles, BlogPosts, CalendarEntries, and all the other unique types of content. You're just re-inventing the wheel if you do, because there are numerous existing commercial and open source CMS tools that can do the job cheaper and better than you.
Unfortunately, I find that one of the most common scenarios is a hybrid web site that needs an attached web application. A corporate web site that needs an attached scheduling tool. A news site that needs an interactive, custom-searchable database. A sports site which aggregates content from an old NNTP-based data source.
Depending on the specifics, you usually have 3 different approaches to this problem:
- Two side-by-side applications. - Pair an off-the-shelf CMS with a custom built application. Copy/paste the visual elements, and loosely wire the two together with a subdomain or some kind of web proxy to share the URL structure
- Extend the CMS - Build a proprietary plugin or extension for the CMS to implement the application features.
- Soup-to-nuts custom application. Build a complete CMS as part of the project.
If scenario #1 is truly possible, it's the best approach. Unfortunately, it's often the case that the two systems need to share user accounts, group permissions (or worse, business logic) and data. Once you link the code and data of the two applications, you actually have a particularly "smelly" case of scenario #2.
And scenario #2 is usually a bad idea, unless you are really committed to the CMS you've chosen. This approach tightly couples your value-adding intellectual property directly to a CMS that generally has nothing to do with your business. If your CMS vendor is out of business in 5 years, you'll probably need to completely rewrite that custom extension to work in some new system. Unfortunately, this seems to be the most commonly-used approach. Radiant's extensions have this problem, and so does the Block/Portlet system in BrowserCMS.
Finally, scenario #3 is just plain wasteful. If your CMS needs are anything but trivial, you're going to spend a lot of time and money building CMS features that have nothing to do with your business enterprise. Unless you accidentally build an exceptionally good CMS tool that you then sell to others, all that money is wasted.
The reason for this problem is that Ruby on Rails is a framework for applications, not systems. The error in all of the reasoning above is that the described CMS project is not a single application, but a system of two (or more) applications.
I've seen some very attractive developments that will help to address this issue in future Rails applications. First, the inclusion of Rails Engines in 2.3 is going to lower the level of coupling for cases where the CMS can be an "engine" within the application. There's some hope that an even more flexible solution may be forthcoming. These solutions help to flip scenario #2 on its head. Unfortunately, this still leaves your application largely dependent on the CMS vendor. You may have trouble customizing the CMS' features without hacking the engine (or "mounted app") code directly.
Over the past few months, I've been working to find better solutions to the issues I've raised here. I'm in the process of building an experimental engines-based CMS plugin, through which I hope to gain some active insight into what makes this problem so difficult. I'll be posting my analysis as it crystalizes. If the CMS turns out to be effective for my uses, I'll be releasing it to GitHub.
For now, I'll simply leave it at this: I believe the solution lies in finding a common "language" for an application to communicate with its plugins, and for those plugins to communicate with one another. In the case of authentication and authorization, this means a plugin needs to know how to ask about the identity and rights of the active user.
Django and Drupal, have made the framework itself answer that question (both Django and Drupal have admin interfaces and user management features somewhat baked in). I'm not convinced that's the best approach, but it seems worthwhile to consider that approach for Rails.
My CMS plugin is opting instead to look for API functions at the controller level to answer these questions (i.e. the plugin assumes you have a current_user() method in ApplicationController, but allows you to customize the name and behavior of that).
Update: Thank you for all the encouraging comments. There are sure some good people out there in the Rails community. I wanted to draw some attention to ferrisoxide's blog post: "Rails is a CMS". This thought is very much along the lines of the experimental development I'm doing. The goal for my approach is to leverage as much of the flexibility of Rails itself for it's feature set.... in that way I'm planning more of a CMS-enabler plugin than an actual out-of-the box CMS.
Update 2: I wanted to also draw attention to Aaron Bedra's comments about CAS, specifically Castronaut as an implementation pattern for scenario #1. It didn't even cross my mind when I was writing this post... and CAS seems to be one of the most under-hyped technologies out there. More on that later.

tagged with: 
Great article! All of us in the biz encounter these problems with our clients. Striking a balance between custom code and off-the-shelf software is a trick indeed. I have found, however, that most clients only use the most basic features of a robust CMS system. IF the client is in this group then it makes sense to go with option #3 - custom CMS development - since in actuality it doesn't require that much time.
I also think that this article highlights one of the reasons I like .Net - especially to get around the authentication issues you mention. the .Net Principal can be shared through applications if used correctly, which makes some of these issues disappear.
Good point about the .NET Principal. It seems most of Rails' more full-featured competitors have made the "current user" concept part of the core framework.
The .NET example is interesting for another reason though. Interactions between two .NET applications don't usually happen at the application level, they happen in the web server (in IIS' settings). J2EE apps have a similar system wherein deployed applications can be assigned security zones. This system actually pushes the entire login procedure out of your application, so that your application merely needs to ask the web server: "Who's logged in?". Authorization and role assignment can then take on application-specific settings after that point.
This same process is possible between Rails and it's host web server, it's just not often used. I believe the reason has more to do with Rails' unique deployment history (Mongrel, Webrick, etc) than with any particular design decisions. It's probably something more applications should consider.
Maybe it would be best to discuss this issues with other rails programmers? Yehuda Katz opened google group about reusable apps: http://groups.google.com/group/rails-reusable-applications
Nothing new since may - it would be great to see some fresh posts there. Could you write a post with your ideas (maybe just link to your blog with short description to not waste time)? :)
Thank for writing about this.
That's my main problem as well. That's why I combine PHP Typo3 with my Rails Apps.
I build the normal website in Typo3 and plugin the webapp.
It's not the best approach, but actually quite useful because the business value for me is the highest at the moment.
I would love to see a rewrite of Typo3 concepts in Ruby/Rails. Typo3 is still the best CMS - Konzept out there.
regards
Rafael
I have a few things to say on this subject.
First, if you think Rails is too restrictive to build a CMS on top of, don't use it. The Rubysphere has a lot of options available, and if you want less presumption from your framework use something like Sinatra. Merb is a good middle ground, which, while it provides a lot of sensible defaults and looks quite like Rails, is configurable in ways which Rails is not.
This is particularly relevant given the advent and widespread adoption of Rack. If you have a sub-app you want to mount to a particular namespace/route, you can use Rack to route to that app. You can currently run a Merb app with a Rails app, or a Rails app with a Sinatra app. Rack will let you do this.
Second, if you look ahead at the topics being discussed for Rails3, both mountable apps, and panel work have been discussed.
Aaron,
have you looked at Comatose CMS?
The reason I use it, is to avoid to CMS lockin that sandboxed systems like Radiant provides. The CMS just becomes part of a bigger whole, and not the foundation for everything.
Perhaps it can give you some inspiration or might even attract you to help develop Comatose ;-)
Excellent article. This is just one of those topics that won't go away, innit? :)
I keep spruiking my own approach, which is to basically to treat Rails as a little language for building web sites:
http://rubyredbricks.com/2009/2/24/rails-as-cms
I'm a bit embarrassed by this, as I've done very little to prove my point and suspect it won't scale. I reckon that your approach (or Comatose for that matter) is probably better as it's still a "little language" approach - enough CMS functionality to get the job done. I'll watch with interest.
In the meantime, I really don't know what CMS features I actually need - so I'm going to defer that decision and just use what Rails and a handful of plugins gives me. I guess I'm going with option #3 -- it may be wasteful, but so would spending my time learning the idioms of a 3rd party CMS (option #2) when I don't know if I need all the features on offer. Option #1 is clearly wasteful.. hmm.. it's tricky..
Again, thanks for a great read. Much food for thought. Good luck with your plugin.
Great post, Aaron. This is a problem that I've pondered myself and I agree that rails engines might have something to offer here. I look forward to seeing what you come up with, anyway!
#2 tends to be used because its pragmatic.
Ultimately, when you write code, you need to work against some API, whether its Rails or BrowserCMS. The main challenge with UIs is how to make them reusable across applications, but still usable and intuitive in each one.
That said, we are following the Engines/reusable code ideas as they go forward, and if they make sense we will look to incorporate them in BrowserCMS. And hopefully, we can add more APIs over time that allow us to expose more behavior to help make #1 less messy.
Either way, I look forward to checking out your solution to help solve the 'integration' challenge.
Patrick
http://browsercms.org
Check out Sport NGIN, a CMS (and more) written completely in Rails.
I've developed what I call a "Effortless backend for Rails applications". Has the same idea than Django. You have your application and then you can install the plugin to manage that content. It's used in many sites, and it's in active development.
http://github.com/fesplugas/typus
(Released under the MIT License)
I looked at Comatose a long time ago, but I haven't checked back recently. It's worth a look again.
Thanks for the suggestion about the reusable apps group. I've posted a link over there.
Nice work, Francesc. Typus is similar to the experiments I've been playing with, although the difference is that it looks like your plugin defines content "types" (i.e. fields, forms, etc) within itself. I've opted instead to use PORM ("plain old rails models") for the content types. As I mentioned in the post though, I'm still in experimental phases of the idea.
Along the same lines as Rack, Python's WSGI allows a similar means of nesting applications using the server and middleware. CherryPy is a slightly more optimized version of this idea in that it formally defines integration points via tools and building a "site" by mounting applications on the "tree".
In any case, I think both Rack and WSGI make it possible to create a cohesive site using a set of microapps. When I did program Rails, this was my biggest complaint coming from Python. There was not a trivial way to write a small utility service or application and attach it to an existing Rails app in a way that doesn't require a trivial integration. Hopefully, as Rails continues to adopt Rack, we'll start to see frameworks evolve to allow easy development of sites based on smaller apps instead of focusing one things like MVC.
Aaron, the idea behind Typus is not adding a lot of dependence to the Rails application, for this reason I decided to have configuration files (yaml) which defined the behavior of the application. I've been thinking in having a DSL, but for now I think people who is using it is confortable with those files. Patches and suggestions are welcome.
Thanks for the post.
I've been dancing around the same idea and project myself. I work for a small consulting/software development company and we've been getting many projects to build a site using a CMS. We, at the company prefer Ruby and RoR but we've been forced to use a certain CMSes like Drupal or ExpressionEngine and we have not been able to make a strong case for a Rails CMS. One of the reasons is our lack of expertise in the Rails CMS world, and that's why I wanted to venture on a project that studies and analyzes the different CMSes available.
Other obstacles include the stuff you mentioned. How to add a CMS to an already existing application in order to handle static pages, blogging, calendars, etc? And I asked that question to the Radiant mailing list and their answer was basically the list of 3 options you mentioned. And they all seemed to require too much work on the infrastructure level for something as simple as just adding static pages.
I will be looking forward to see the results of your project and how you'll go about solving this problem. And maybe I will be able to also share my findings once I get the time to the stuff I wanted to try on this subject.
Have you thought about using solution #1 and tying things together with a CAS based solution? That let's you keep user accounts and gives you the "single sign on" feel. There are several projects out there that can help you out including Castronaut (http://github.com/relevance/castronaut)
Nicely summed up! I regularly hear people new to Rails expound on how they're going to combine my favorite CMS with their favorite shopping cart application. It sounds easy enough but it rarely gets done.
Maybe it's a blessing because when those kinds of solutions become common place we're going to have a lot of mixed up applications frankensteined together. As it stands with the high price of combining different kinds of thoughts together, we're left with more single purpose website. I don't really mind that. I realize everybody wants everything now; but as a web developer, I find these quaint limits kind of refreshing.
I'm sure when it's easy to combine this and that I'll be doing it. I won't be able to help myself. Clients will request it and I'll do it without even considering that maybe a lot of these combinations will create excess overhead and duplication of actions.
I am using Comatose very successfully in one application. There were a few hiccups early on, but the latest versions have been working out really nicely. Adding a lightweight CMS into the application itself, was exactly what we needed.
This question was really my bread and butter for 3 years when I was freelancing for small clients and working at an agency.
The agency in the early 2000s answered the question by developing their own in-house CMS and amortizing the cost over hundreds of clients. I think this can work really well if you have a lot of clients in a specific niche. In our case we had too many types of clients, and frankly the code sucked, so we started using Expression Engine and Drupal. At the budgets our clients had it makes it an easy decision because it's either an existing CMS or nothing. But here's where it gets hairy...
Whereas Rails has a very natural level of abstraction that suits almost all web applications quite well, a CMS requires a great many more assumptions. I consider Drupal to be a fairly optimal implementation of the idea of an extensible CMS. The architecture goes to great lengths to give you all the hooks you need while still providing a nice out-of-the-box experience and tons of canned modules. It's quite impressive the amount of customizability that Drupal gives you.
The only problem is it comes with a ridiculous amount of overhead. If you work exclusively with Drupal for a couple years and fully understand it inside and out you can whittle away at the conceptual overhead, but you're still using a system that makes all kinds of assumptions (eg. every page is a node) that could paint you in a corner or at least require heroic measures to work around. You start making all kinds of small usability and design tradeoffs just to go with the flow.
In fact dealing with Drupal is what really drove me to start working exclusively with Rails. I eventually joined a startup, and let me tell you, what a relief it is to dedicate serious time to a single application instead of all these half-baked one-off projects.
Fundamentally what it boils down to is that a CMS has to make assumptions to be effective, and every assumption you make is going to de-optimize the framework for certain sites or apps. As such I think the original dilemma is universal and the fact that Rails is light on open source CMSes is just incidental.
I do a lot of work with Drupal and likewise this work has led me to search for a Rails-based CMS. Why? Drupal is fairly targeted to beginner developers, "you'll never need to write code". This is great if that's what you want, but as a professional creating websites for clients you are happy to write code and in fact will probably end up doing so to gain the customisation you need.
There are many great developers building solutions on Drupal, but this leads to the second problem: coding in PHP is no fun.
Third problem is that coding for Drupal means learning a lot about Drupal itself, making you more and more a "Drupal guy".
There are so many modules for Drupal but for most things you want to do, inevitably it's just easier and better to build a customised solution with CCK and templates or Views (for those that don't know, CCK is sort of a way of saying things like "a certain category of page may have a certain type of file attached and then will display it this way").
So why use Drupal at all? Because you get a lot of great stuff out of the box. In 20 minutes you have an installation with user management, page and menu management, WYSIWYG integration, content types, SEO features, advanced i18n handling, and basically a lot of stuff that would take a long time to code yourself if you worked out all the details properly.
If I write code, I want to write it in and be practising Ruby, not PHP/Drupal. If someone can provide the core quality functionality of Drupal in a Rails app which assumes I know how to code and which I can then extend to any particular client's requirements, that would be great!
Partially "Rails is a CMS" is true... but there are quite a few things you have to build to have a really nice polished CMS. And for small business clients which are often those who need CMS', time/price is of the essence.
Really interesting article/discussion and very relevant to us. We've been building Rails apps for years and currently use various, non Rails, mainstream open source CMS products for projects that are mostly "web sites" (i.e. not too much custom development). We are currently evaluating Rails CMS products to enable us to ultimately use a singe technology stack for all our projects. It seems like Radiant and BrowserCMS are the favorites but they they both have drawbacks (Radiant too simple, BrowserCMS too new). At the momement we are leaning towards BrowserCMS (it appears to have all the features we need) and we're hoping that the community will grow quickly. Does anybody know of other options we should consider that are i) well architected i.e. the "rails" way ii) as powerful as BrowserCMS and iii) are likely to grow a strong community quickly?
Comatose is interesting and has the right approach. I say that after having set up a demo, but I've been spending quite a bit of time in the CMS space recently, and I agree about not being landlocked into a CMS framework which invents its own ways of doing things.
As an alternative to Castronaut you might look at RubyCAS - it's a fully functioning CAS server, I think it's up to date with 2.0 of CAS. There's also a client (which is a Rails plugin).
Great article.
This is the way out of the dilemma!:
http://www.silverwirt.de/using-the-silverstripe-cms-with-rubyonrails/
Hi !
I wrote a post with some ideas raised by this post on is Rails a CMS?.
These ideas mainly go into the direction pointed by Fletch: it depends on the amount of time/price available and the kind of polish expected by the client.
Gaspard
Here a german RoR-developer´s search for a CMS, described in german language:
http://upstre.am/2007/02/25/nochmal-zum-thema-rails-cms/
Very important topic! Thanks for this one.
In my dream #1, I can quickly code applications using Rails, and quickly integrate them within Drupal and Joomla! In my dream #2, those CMS are coded using rails.
Lots of people understand some techniques of persuasive term paper creating, but this doesn't mean they will create high quality essay papers, but a custom writing service can help to create the persuasive term paper of great quality and improve writing ability of some students.
Sorry - Grails already beat you to the punch: http://www.grails.org/plugin/weceem
Have you looked at http://www.refinerycms.com? From what I've seen so far it looks awesome.
And it stays pretty much entirely in the vendor/plugins directory (it is itself composed of several plugins, making it modular), leaving you free to put whatever application stuff you want under app/.
And (I think) you can override Refinery's defaults by putting your own version under app/...