Ruby on Rails based CMS

Posted by ferrisoxide
on Tuesday, February 24

I've put this up as the original page at http://wiki.rubyonrails.org/rails/pages/Ruby+on+Rails+based+CMS seems to have been trashed. This was retrieved from Google Cache, a snapshot of the page as it appeared on 16 Feb 2009 04:47:48 GMT. Apologies for the weird layout, but I just wanted to make sure the reference document for the "Rails as CMS" article was available. I can't promise that any links work.

Ruby on Rails
Ruby on Rails based CMS

Read the discussion on the mailinglist as a starting point.

Also ask yourself, why build a CMS in ruby/rails at all? Why not just Integrate Rails with a CMS?

Still let’s gather some requirements for a rails-based CMS. I imagine there are many people writing or considering writing such a beast.

Revised Feature Suggestions

Things I’d consider essential:

  • Create and edit via redcloth/etc from web
  • Access control lists
  • Full customization of layout and style
  • Pretty urls (no /node/2235133/)
  • Subpage Content items, may be referenced freely by multiple owners (graph not tree)
  • Staging
  • Versioning
  • Lives as a component in rails, can reference content in a way similar to render_component in views
  • Should produce W3C standard (x)HTML/CSS/Accessibility web site

Things that are more dubious:

  • Edit via blog tools
  • Publish approval
  • File/image attatchments in CMS (rather than referenced from a apache hosted directory)
  • All content and templates in database

Rationales:

  • Allowing content items to be units smaller than a page and referenced as a graph would allow the most flexibility, but it also appears very complicated.
  • Hosting everything in the database would simplify deployment in situations where there are multiple front end servers. But, it’d likely require some sort of caching mechanism which could get complicated.

Other Ideas

  • Cool URLs Don’t Change: http://www.w3.org/Provider/Style/URI
  • Binary Content doesnt have to be in the database, BUT should not be directly accessable through “apache hosted directories” (like someone wrote above), because a good CMS must also check permissions on those objects

Requirements in the Real world
(ideas by lastobelus)

IMO, a CMS that DOESN’T have content items as units smaller than a page is a complete waste of time in my world (internet-focused advertising agency)..

Also essential is that the same ContentObject can be rendered differently in different places. Referenced as a graph would be the best way to do this. TemplaVoila of Typo3 is a good start, but suffers from lack of a global render context, and is (almost) strictly a tree.

A global render context and/or graphInsteadOfTree is important, because content objects are: a) sometimes rendered in two different places, but should only be edited once, and b) sometimes sub-templates need to decide how to render based on what other (arbitrarily included) subtemplates are present or have done.
Any sub template should get hooks at start render & end render of the whole template, its immediate parent, and itself. Optionally, it should be able to register for hooks at start/end rendering of some arbitrary subtemplate if it happens to be in the template (may be difficult to do this efficiently enough to be worthwhile). Or use two pass render, and any node can use something like xpath or dot notation to check out other nodes.

If you do these admittedly difficult things, you go a long way to eliminating the problem that most CMS’s have: when given a complex design to implement they do the first 80-90% of the work for you, but make the last 10-20% so difficult you end up wishing you’d handrolled the cms for the particular template. In my industry, the design is king. If the template design doesn’t breakdown neatly into a hierarchichal tree, oh well, TFB for you.

Another thing, while I’m at it: eliminate the distinction between mapping to inner tag and outer tag. It’s a trap. The map should ALWAYS be to the whole tag, the attributes set in the tag of the static template are the default attributes, and they can be overridden now or sometime in the future. To put it another way, there is no attribute mapping, only tag mapping. Of course, this already implies your data object can’t just be a tree mirroring the html.

Lastly, it’s good to have three levels of mapping not two. The complete map is: ditView, ContentObjectGraph, ContentGraphDefinition, HTMLTemplate. The ContentGraphDefinition is the thing you stick on a page. It has a mapping to actual data (the ContentObjectGraph), to one or more ditViews, and to one or more HTMLTemplates. If you do this, you can do cool things like having different people see totally different edit views for the same content for different purposes.

In the real world, staging is NOT an option. It often trumps access control lists, actually. 2 or 3 full-time people can generate a LOT of content, and they don’t care a whit about access control — what do they need it for? But tell them that there are going to be brief periods of time when their site is in an indeterminate state… nuh-uh. And agencies really need systems with two levels of staging, or at least content staging is separate from template staging. The client needs to do content staging, the agency needs to do template staging.

Pretty URLs
(ideas by technoweenie)

There needs to be a way to map URLs to modular controllers. For instance, you could map /blog/ to a blog controller, or /about/contact to a contact controller. This way, the URLs fit the site hierarchy and not the controller layout. This can currently be done with Routes.

Example:


map.connect 'about/:page', :controller=>'pages', :action=>'view',
  :page=>'index.html'
map.connect 'news/:year/:month/:day/:slug', :controller=>'weblog', 
  :action=>'view_html', :year=>nil, :month=>nil, :day=>nil,
  :slug=>nil, :requirements=> {:slug=>/.html$/} 
map.connect 'news/:year/:month/:day/:slug', :controller=>'weblog',
  :action=>'view_xml', :year=>nil, :month=>nil, :day=>nil,
  :slug=>nil, :requirements=> {:slug=>/.xml$/} 

This is just pseudo code for now.

Other CMS’s With Cool Features

I’ve begun progress on writing a CMS such as this. Never got around to finishing it. Now that Routes are out as well as ActionWebService, I’m thinking about starting it again. These suggestions will help me make it better. (Matt Moriarity, cooldude127 in IRC)

The Great Ruby CMS (TGRCMS) beta

Rubricks

Geego cms

Very flexible RoR cms. Geego puts no restrictions on data structure or final output and has built in image manipulation(resizing + cropping) and multi-language support.
MIT license.

Magnolia CMS

Worth checking out from a usability standpoint. You have to check out the demo and actually edit a page before you can say you looked at it (hint: right-click). But it’s got some kind of fancy Java driving the edit feature, not sure if you could do that with Ruby/Javascript (yes, a thinly veiled dare).

(once logged into the demo, try visiting this page. No Java, just JavaScript)

Bricolage

Originally written for Salon, now used at Macworld.com, and The Register Has support for staging, versioning, pretty URLs, ACLs, complete customization via Mason or HTMLTemplates, Publishing approval, and sub-page units; supports Output Channels to for different output formats (i.e. HTML output, PDF output, RSS output, etc.). File/Images aren’t “attached” – you first upload the file/image into the system, then relate the article to them via a “Related Media” element (same idea works with Related Stories). There is a patch flowing around that lets you upload your files while you’re updating your story tho. It publishes files by merging the templates with content and “burning” them into files (static HTML, SHTML, PHP, etc.) and distributing them to one or more destination servers.

Drupal

Essential CMS with few core modules, It has a nice plugin/module system that permits a fine tuning of the CMS.
Every feature of the modules can be or notenabled for groups or single users in read-only and write.
With the right moduls Drupal becames the best, blog, portal, forum or ecommerce site.

G2 Publish

G2 Publish is a new type of content management system aimed at the small and medium business enterprise market. Unlike a lot of other CMS available today, Publish aims to focus on ultimate usability over advanced feature sets to begin with, rolling in new features as the product is developed.

Still in very early development, the main site is primarily a blog of development progress. Timescale for public preview is March 2006.

TYPO3 CMS

TYPO3 is a small to midsize enterprise class Content Management Framework offering the best of both worlds: out-of-the-box operation with a complete set of standard modules and a clean and sturdy high-performance architecture accomodating virtually every kind of custom solution or extension.

Scoop

Scoop runs some huge community sites like Kuro5hin and www.dailykos.com. Extremely configurable.

Almost everything in scoop is editable through the web including all html source. Blocks and boxes and other elements can be included in the html using specific syntax which could be easily replicated with erb.

alahup!, the Next Generation CMS

Joomla

Dead projects

MuraveyWeb 0.2

AdminPages

Last update on RubyForge in 2006
A CMS with a nifty drag and drop based interface, implemented as a Rails engine.
Supports nice URLs, custom content elements and a sortable tree-based page administration interface.
AdminPages can be used to build and administer design-focused sites. A layout editor can be used to define content elements of a layout (title, keywords, header image…). A scaffold template is created, which can be extended for the final layout.
It is fairly easy to define new page elements.

Demo site: http://adminpages.flowdev.de

development page: http://rubyforge.org/projects/adminpages/

Other CMS Resource Sites

Making a Better CMS and Why Content Management Fails from Adaptive Path are worth a read.

Also the CMS Matrix lets you compare a huge boatload of CMS’s, open-source or not, by their features.

FreeWebSoftware.org is a big list of GPL web software.

opensourcecms.com showcases “open source” cms’es


WYSIWYG editor ideas

And while I like redcloth I think a WYSIWYG editor for text/html articles/documents is definitely key. Mambo allows you to choose between a couple the most advanced being FCK Editor. But there are plenty of others out there.
(TextPatternhtml_preview has a nice solution that also supports Textile, but you can’t yet type in the Preview, i.e. WYSIWYG. JotSpot also uses a nice WYSIWYG editor for its wiki)_
HtmlArea is an open source WYSIWYG editor. Cross browser (Mozilla/IE AFAIK), and even includes an aspell powered spell checker. The last version of HtmlArea? 3.0-rc1 is from Mar 1, 2004 and has known issues with Firefox. Most people suggest going with FCKEditor.
TinyMCE should also be noted.
Another good, yet not well known editor is kupu. It works well in both IE and Firefox and is really lightweight.

Problems with WYSIWYG

I see the following problem with WYSIWYG-editors. HTML isn’t rendered identically by different render-engine (as we all know). Any WYSIWYG-editor relies on some render-engine. That means, the user must rely on how a page LOOKS rather than how a page is structured. This must lead to errors, if the user isn’t a extremely disciplined worker.

For example, if a line consist out of an inline icon, followed immediately by a link and links have the text-decoration underline, Firefox correctly shows different behavior, whether the link includes the icon or not. If the link includes the icon Firefox underlines the icon, too. If it doesn’t, Firefox doesn’t underline the icon. But IE isn’t underlining the icon no matter it’s included by the link or not. So in a WYSIWYG-editor that behaves like IE (p.e. some javaeditors seem to use the html redering-engine of the host-browser) you have no chance, distinguishing both versions of the same content.

I have set up a CMS for the intranet of a design-school here. I used Textile for html-formating. About 20 professors and teachers with extremely different computer-skills are feeding content into this system. It turned out, that the code all those people produce in this CMS is highly consistent and mostly free of errors. None of these people had severe problems starting to use Textile, but of course they needed instructions.

No WYSIWYG-editor works for people who don’t know what they’re doing. It would have taken the same or higher effort for those people to learn how to properly use a WYSIWYG-editor.

Additionally to start of with Textile you need just half a dozen commands (h1, h2, links, pictures, bold). For trickier formating-stuff more knowledge is needed. In my case this restriction turned out to be a big plus. People couldn’t change the color of headers ([edit]click [textcolor]click [pink]click) without learning more format-tricks. This prevented the unexperienced from doing weird stuff.

About the User

The best way to get people to use a Content Management System (or any system) is to design a system that people want to use. To do that, you help them meet their goals more efficiently/effectively/enjoyably. So maybe the conversation should start off with, who are the users (and who are not the users), and what are their goals, skills, and motivations? What are they trying to do and why, then how can we help them do that better/easier and have more fun while they do it?

The user doesn’t care how easy the templates are or where uploaded files go to, he just wants to post something in the right place, include a picture and have it look professional. The user also doesn’t care if developers masturbate at night to how beautiful the code is, so go ahead and make the code pretty too (if you’re into that sort of thing ;), but focus on the user first to create something helpful and loved. Focus on making the user feel smart, happy and successful and you will be too.

If Ruby/Rails comes up with a CMS that any idiot can throw on the intranet/internet and everyone in the company/group can successfully use it and enjoy doing so and not want to kill the guy that inflicted it on them, maybe that’s one possible goal. Of course if the goal is more of a developer-masturbatory Ruby-based CMS module deployment base allowing developers to escape the tyranny TheOtherLanguages?, that’s fine and useful too, but trying to do both at the same time can lead to satiating a few while not making anyone really happy. But an intellegent CMS that did amazing things for users could do a lot to further Ruby’s adoption, and if it also did amazing things for developers, well then we could all break out the lube I guess.

Probably good to establish a list of things this CMS is not or won’t do too. Which users are we not designing for? Complete Idiots? Expert Developers? Retail? The goal of it all is to end up with a desciption of a user that can be the focus of the design, one which if you make that person really happy you’ll probably make a broad range of people happy, and then you can forget about all the stuff that the people you’re not designing for want, maintain KISS-compliance and establish focus in the development team. All the decisions become much more apparent once you have that focus.

Very Preliminary List of Some Possible Types of Users

  • Non-profit
  • Corporate/Intranet
  • Retail Web Site
  • Municipalities/Government/Libraries
  • Confused Blogger Wannabe
  • Homepage for Services
    • Lawyer
    • Chiropractor
    • Bar
    • Restaurant
    • Professional Developer
    • Band
    • Web-based services

So a corporate user is going to have different goals than a chiropractor, or a non-profit user, or a restaurant owner. You’re not going to make them all happy simultaneously, so pick one.


I have been working on a CMS myself, albeit maybe 1 hour every few days or so. It will focus on making a static-like website editable. It will revolve around a typical directory structure as in: mysite.com/directory/page. It may at first only give you tree-like editing of the site structure and “edit this page” functionality.

Following the whole KISS principal, you will be able to edit your template, site structure and pages. That is it. No workflow, no editors, publishers etc. etc. You login, CRUD your pages and directories and change the look of your site.


Rather than trying to write a universal CMS (which from my experience usually isn’t any good and needs rewrites each time you start a new project) we should focus on writing the tools needed to quickly write a simple CMS. That includes a “admin” mode in which the admin tools embedded in all pages become visible. We also need a toolset to scaffold content editing.


I think you’re right Pie. MuraveyWeb seems to be kicking butt and taking names as far as creating an out of the box solution for most users needs. I’m switching focus to being able to do ‘CMSy’ things in more customized applications. So now I’m instead looking at things like storing views in the db, referncing web gui text via an indirection that supports internationalization, providing quick admin gui interface helpers, etc.


“alahup!, the Next Generation CMS” is definatly NOT what I’d want to use ever. If to use an UI API, then please use anything OPEN, like XUL just for example.
MuraveyWeb has nice JS UI, its fast and works! Bricolage, from the CMS feature side, looks very nice. Versioning, Staging, Integrated Workflow Model.
Basically I think CMSs should have only very few features in the core and should have a nice API to extend them. Also hint that the two most important things cannot be solved by any CMS: screendesign/ui-design and creating content

OpenACS? (Open Architecture Community System)

I think we should take a lot of ideas from OpenACS Phillip Greenspun’s brainchild.

It has a unified data model that is used by all the components and allows for very creative user interaction.

If you want to see it in action in a community visited and used by millions of people check out: Photo.net




I’ve put up a site and proposal for “RailFrog”, a user-friendly, open-source web site deployment and content management system built with Rails; producing well structured and standards-compliant pages with Web 2.0 goodness. I’m just helping launch and spearhead the effort; feel free to jump in and help make this crazy dream of ours a reality.


I am no DB expert, but pretty much every “how to create a fast, reliable database” will tell you that storing large files (images, etc) inside the database itself (BLOBs, etc) is a really bad idea. Instead, have the system generate a unique identifier, rename the file, drop it in a file pool, then store a reference to the file in the DB. The middleware can access the reference, locate and rebuild the file. If you think about it, this method makes the most sense.


I disagree strongly with the sentiment above. Do that and you are tying your database to stuff that isn’t in the database. How would you, for example, do backups / restores to a known state? The file system isn’t covered by database transactions, so that would leave you SOL. There’s nothing to stop someone outside of the application crapping on your ‘binaries’ directory. What happens when you realise you need to scale your application, and have the database running on one machine and a number of ‘client’ rails apps running on other machines? Databases are made for holding data. It’s what they do. Most of them do it quite well. Leave them to their job



Clearly the comment above was not posted by a DBA. BLOBs in databases are a bad idea, and poor performance is usually the result. There are ways to handle the issues above, they are certainly not new problems.


Isn’t Rails practically a CMS already? CMS is basically CRUD with some way to organise data. That managment system is the big thing which changes btween different CMS’s. Would it be better to focus on making Rails even better at making custom CMS’s, rather than trying to make one CMS?

What do we want to do with a CMS that doesn’t come right out of the box with Rails? Can we add it to Rails?


Maybe I’m missing something but it seem like a CMS/Portal hybrid is needed for Rails site development.


Drupal’s Taxonomy structure is really valuable for sites that have complex keywording needs.



Why not just create a package of generators that can bring a default rails install up to a default rails CMS framework ready to fill in data and generate scaffolding?


A CMS should be another tool in the toolbox for Rails developers. It shouldn’t enforce a new or ad-hoc way of developing applications. The CMS should not take on the role as an application development framework. It’s a view technology basically.

In this perspective, would it be possible to build a web front-end to the whole Rails system with some extra functionality for content management (a content controller)? Maybe we could extend the on-disk template engine to find view components in the database. You could store your .rhtml in the database and manage them from the web front-end. Content fragments could be structured according to controller/action/contentpart and stored in the database. These contentparts would be loaded automagically as a before_filter for each controller and placed in views by helpers in an easy fashion.

Any controller in the application could make use of the content system to place dynamic information for it’s views. The controller(s) in the content system would also provide admin functions/views and special functions for more content oriented sites (like a traditional CMS). The difference with this Rails-centric CMS would be that it still will let you develop advanced web application functionality in a sane way.


It occurs to me that Rails is flawed for any real world application that actually integrates into an already existing system, be that a data store or a piece of business intelligence. Why is this relevant to talk about a CMS? Because a cms has to have the ability to interact with more than just its own datastore. A true cms does not rely on its own defined datasource but rather manage and dictate the information it has been defined to handle. The debate earlier had about “do we store things on the file system” is actually a great example of this. Why? Because the file system is just another datasource that a cms needs to manage and handle.

The issue I see with ruby on rails at this moment in time is it is a very solitary framework. I dont doubt for a second that the controllers can be used to handle connectivity to other datasources but you are immediately breaking out of the rails framework. Essentially the problem lies with the models insistance of using plurals to build the relationships. Its a great idea and I love it, but it seems an inherent flaw.


In regards to above:

The plural functionality isn’t mandatory, nor is it an inherent flaw! It simply makes life easier for developers who follow the default naming conventions. If you are integrating with an existing data model then it’s perfectly acceptable to simply tell Active Record what the name of your existing table is and what it’s primary key is called. You need to be more specific when defining the relationships as well. None of this makes it more difficult than any other method of integrating with existing data.


I’ll have to agree with the above poster.
Citing “Agile Web Development with Rails”: It’s less about giving up your own way and about getting productivity for free.

You don’t have to use the naming schema, but there’s no reason not to if you’re building something new.


some thoughts about a CMS:
the web’s main feture is that it connects people from all over the world. so as site developer some people would want to address an international crowd (sounds logical – right?)
now, al the 2000 or so CMSes already available fail this very basic demand which in my view is more importent than all the bells and whistles as it is a core feture that must be at the core of the framework and api of a cms.
there are two main isuses here (which are very different) I18N and L10N.. most cmses support the later to some degree while i speak of the former. the cms should allow me to present different content to different users like in the following examples: an international site that shows the english content for UK,US,… with design left-to-right based.. the same site gives the arabic or hebrew version for the appropriate people with the same design but right-to-left oriented, a traditional chinese or japanease that goes top-to-bottom, etc.. so each user gets a version suited for his need without makeing 5 different templates(per languge) and allowing the webmaster facilities to translate his content and manage the logic of his templates. that’s the killer feture that isn’t present yet, and translating the admin interface is very much low priority, though many cmses follow exactly the opposite of what i described, the content given to the user must have IMHO a higher priority than the admin interface. and the cms must provide for that. everything else is an addon.


I would really like to see MODX but written in proper programming language such as Ruby. There’s just something really nice and simple about the way MODX have done things.

http://www.modxcms.com/

Nothing right now in the rails world comes close. Having also used Drupal, Joomla and Zope/Plone (which is nice but just takes too long to develop anything new), I’ll be deploying websites in PHP for the foreseeable future. But then why not, as productive as Rails is, the PHP guys are still a few years ahead in terms of CMS development.


Addressing the idea that “Isn’t Rails practically a CMS already?”. This resonates – maybe Rails is just a way to describe CMSs (amongst other things). I’ve started to blog on it, but the only way to prove this notion true is to actually build and manage a website using Rails. More to follow.


For a novel approach to building CMS sites, there is zena, a rails based CMS that puts the heavy duty tasks in the Model (secure access, validation) and the View (presentation, usage) through a powerful templating language based on xhtml. The powerful templating language avoids most of the plugin/module CMS philosophy for a design that is more content oriented.

In zena, you worry about what you deal with (mushrooms, receipts, walks) not how you have to fit these into pre-developed modules (calendar, polls, event).

Comments

Leave a response