Note: I have explored Browser CMS recently. It is quite new CMS or rather it is very new to communities. However, i think it may worth saying something about it as well, so this post has been edited to include BrowserCMS.

If you are looking for CMS in ruby on rails, the most popular ones out there should be Radiant CMS and Refinery CMS. And there is a relative new CMS called Brower CMS. I have spent some time looking into each of them in order to select a CMS for my projects. There is no straight answers telling you which one is better. If you understand all of them, you will know that why I say so. All of them have their own advantage and disadvantage, so which one to choose is really depends on your needs. I will explain the difference between Radiant and Refinery and Browser CMS in this article.

1. Rails and Ruby version support

Radiant: The current Radiant version is 0.9.1. Radiant is using vendor rails, meaning that when you install the Radiant gem, it comes with its own Rails as well. For Radiant 0.9.1, the Rails version is 2.3.8. You can’t change rails version, as it is using vendor rails unless you modify the Radiant source code. However, for Ruby version, Radiant 0.9.1 supports 1.8.6 and 1.8.7. I tried on 1.9.2, it doesn’t work. I managed to fix some compatibility issues, however, there are still more. So I gave up doing that. Future version of Radiant will definitely support Ruby 1.9.2 I believe as there are already some works done in Radiant branches.

Refinery: Refinery is the only popular Rails CMS out there now that supports Rails 3, or officially supports Rails 3.  For Ruby, it should be 1.8.6 above. Of course, since Refinery supports Rails 3, so you should use Ruby 1.9.2.

Browser: Supports Rails 3. Highest Rails version 3.0.9 with Ruby  1.9.2.

If you think that you definitely need a CMS that supports Rails 3, then the last two may be the options.

2. Integrate with Existing Rails Project

Radiant: When you create a Radiant project, you will see that the project folder doesn’t comes with an app folder, which means it doesn’t have controllers/models/views, where you can add your custom controllers to create dynamic pages. Even when you add load path to environment.rb, the routes simply won’t be loaded as well. However, the good thing is that Radiant comes with a very powerful extension systems. If you create an extension, you are able to have your own controller/models/views and even routes. Basically, your extension would be loaded like a Rails projects. And there is also where you could put your own custom controller/views etc. That’s to say, if you want to create some dynamic pages that can’t be managed by the CMS, what you should do is package all those pages as an extensions.

Refinery: With Refinery, it is much easier to integrate into existing rails project or the other way round. In Refinery created project, you could see the folder structures still like how a normal Rails should look like. It still have app folder, where it contains controllers, views, models. So you can organize all your customs controllers views inside there, just like a normal Rails project would. Of course, you need to add your routes in routes.rb. That’s why I say Refinery is very easy to integrate into other projects.

BrowserCMS: BrowserCMS created project behaves like normal Rails application with BrowserCMS required as a gem. So if you want to create your own custom controllers/views, it is easy. And you can use existing layouts created in the CMS as well.

3. Multiple Layouts

Here is an important difference it will greatly decide which CMS to use.

Radiant: Radiant has a very flexible structure. It has pages, layouts, snippets. Snippets are those pages or parts that you think that you may reuse in a lot of pages, so you can organize it into snippets, like Rails partials. So in layouts or pages, you can call that snippets easily with Radius Tag.

<r:snippet name="snippet_name"/>

For the whole site, you can define multiple layouts pages, so different pages can use different layouts file. This is quite important, as you don’t always want every page of a website looks similar.

Refinery: Refinery are quite different in how they organize the pages. In Refinery, the pages are still organized in the Rails way. When I say Rails way, it means that it have one layout file in the views/application where every pages when render are going to use this layout unless specified differently. When you want to modify this layout, there is no way to do so in the admin panel. What you have to do is to use Refinery override command

rake refinery:override view=pages/home

This will create the corresponding view file in your projects app/views/pages/home.html.erb file. Then you can modify the erb files. This is how you can modify the views. So the admin panel is only for you to edit the page content, and change some css. That’s it. If you want to do something like modify layout, you have to be a developer to do it. So the whole site is sharing one layout as well. This is usually a big problem.

BrowserCMS: This is a bit different with the other two CMSs. You are able to create any layouts in the admin panel. And this is layout that you can see exactly in any Rails application because BrowserCMS use erb template system to allow you to create template.

What’s more, you are able to define partials and write partial contents in admin panels! This is extremely powerful. However, with the ability to write ruby code in the template, it has expose a very serious security problem. If someone is able to hack into the password of administrator, he is able to delete the whole file systems in your server and download the whole database.

4. Multisite support

There is an multi site extension for Radiant. I have tested it out and it is still working for Radiant 0.9.1. However, Refinery doesn’t support multi site. BrowerCMS doesn’t support this as well.

5. Admin Panel

Radiant is using Prototype as the admin panel javascript. Refinery is using jQuery as the default javascript library. So I have to say that Refinery has some advantages here. Although on the front end, you don’t have any difference as you can choose any javascript library to use. Jquery is gaining more and more popularity that it is the dominate javascript library with active development and support but not Prototype. Since Radiant is using Prototype in admin panel, it means that any extension that needs to modify the admin panel may use Prototype as well. When I say, it means that the extension author can still choose to use either jQuery or Prototype. If you hate Prototype a lot and are willing to convert the existing admin prototype javascripts to jQuery, then what about those extensions that already developed with prototype?

BrowserCMS: It is using jQuery in admin panel. However, it has small small layouts issues in IE, and it is best viewed in FF. The browserCMS comes with drag and drop of pages function. However, I tried and find that you can drag and drop the page for one time, if you want to do it again it is not working anymore. This is small issue which may be fixed, however I feel that this is released so I expect everything should be working fine.

6. Extension

When it comes to extensions. Radiant of course has more extensions. Reason being:

1. Radiant has been out much longer than Refinery

2. Radiant’s core library is very light weight. e.g it doesn’t have WYSIWYG or WYMeditors, you have to install extensions. However, Refinery comes with all of them in core. So by using Radiant you must reply a lot on third party extensions. With Refinery, you either reply on the core or rely on yourself.

BroswserCMS and Refinery has very few extensions.

7.Version Control

Radiant: Radiant doesn’t come with Version Control for pages. However, there is one extension out there doing this. I tried but it is not working anymore for Radiant 0.9.1. You have to update the extension if you wish to use it.
Refinery: I think it doesn’t have and there is no existing extension does it.
BrowserCMS: It comes with version control for pages and even for files and your custom defined content block! This is really great.

8. CSS/JS editing

Radiant: Radiant manages css/js just like a normal page. So you are able to edit them freely in the admin panels. If you have version control set up, you can apply to css/js files as well.
Refinery and BrowserCMS: It doesn’t support editing css/js in the admin panel. You have to upload as file. This is quite inconvenient sometimes to users. Good thing is that since css/js are organized as files, you can do caching and sprockets to enhance the performance.

9.WorkFlow

The good thing about BrowserCMS is that it comes with workflow. It means that you can configure it so that some users can only edit contents, and it needs to be approved before it can get published. However both Radiant and Refinery doesn’t have it.

On the other hand, Radiant is actually very flexible to extend both in functionality and Admin UI. So we can write a custome work flow for Radiant. However, since workflow comes with BrowserCMS, you have to evaluate if it fits your needs, as it would be very difficult to modify if it doesn’t.
Read the rest of this entry »

Web Cache is very important to a website that has very complex DOM structure or have a lot of javascripts/images in the page or a page that needs quite sometime to render on the server due to the complex logic that it has with the web application. You can think of web cache as a middle layer between client and web application on the web servers. If a request comes in, the web cache will check if the same request has come in before or not, if so, and the page is still fresh, then it can server the resources from the cache, meaning from the file system, instead of requesting from the web application again, which may have to generate contents dynamically. Thus it reduces load time.

 

There are three different kinds of web caches, namely Browser Caches, Proxy Caches, Gateway Caches. If you need to understand the difference, you may want to refer to this article ‘Caching Tutorial‘.

 

As for Radiant CMS, the biggest advantage is it has Radius Tag. Radius Tag acts like partials in Ruby on Rails. It can serve some dynamic contents so you can embed some logic in it as well. e.g. it has <r:if_content>. So with Radius tag, you don’t have to duplicate contents or pages. It is quite flexible. However, this biggest advantage also becomes the biggest disadvantage for Radiant CMS in my point of view. Developers can even define their own Radius Tag that render anything that they wanted. Thus for complex site, most of the time, the html structure is very complex, which also means that it may have a lot of Radius Tag. So the rendering of the pages takes up quite some time.

 

So for Radiant CMS, cache is quite more important. Especially for a complex site that uses a lot of Radius Tag. Radiant CMS make use of Rake::Cache to do the caching. According to rack::cache home page, “Rack::Cache is suitable as a quick drop-in component to enable HTTP caching for Rack-based applications that produce freshness (Expires, Cache-Control) and/or validation (Last-Modified, ETag) information”. So you can see that Rack::Cache actually is a kind of browser cache. By specifying the cache-control and Etag in the response header, it is able to load resources from cache to reduce the load time and bandwidth. In order to enable the cache, you have to make sure in your environment.rb you have the following configuration:

config.middleware.use ::Radiant::Cache

When first request comes in for a page e.g. home page, since it is a new request Rack::Cache will pass the request to Rails application and generate the page and return the response to client. You will see something like the following in the response header: (click on the image to see bigger one)

 

Ok, now it may be a good time to talk about how cache validation works:

The most common validator is the time that the document last changed, as communicated in Last-Modified header. When a cache has an representation stored that includes a Last-Modified header, it can use it to ask the server if the representation has changed since the last time it was seen, with an If-Modified-Since request.

HTTP 1.1 introduced a new kind of validator called the ETag (Entity Tag). ETags are unique identifiers that are generated by the server and changed every time the representation does. Because the server controls how the ETag is generated, caches can be surer that if the ETag matches when they make a If-None-Match request, the representation really is the same.

Almost all caches use Last-Modified times in determining if an representation is fresh; ETag validation is also becoming prevalent.


In terms of Rack::Cache, it stores cache entries in two separate configurable storage areas: a MetaStore and an EntityStore. Etag information is stored at MetaStore.

 

The MetaStore keeps high level information about each cache entry, including the request/response headers and other status information. When a request is received, the core caching logic uses this meta information to determine whether a fresh cache entry exists that can satisfy the request.

 

The EntityStore is where the actual response body content is stored. When a response is entered into the cache, a SHA1 digest of the response body content is calculated and used as a key. The entries stored in the MetaStore reference their response bodies using this SHA1 key.

 

In terms of Rails, Etag is generated in Rails Core under /actionpack/lib/action_controller/response.rb

def etag=(etag)
      headers['ETag'] = %("#{Digest::MD5.hexdigest(ActiveSupport::Cache.expand_cache_key(etag))}")
end

And Etag is used in Rack::Cache to determine if the page has been changed. The browser will issue with a If-None-Match request, with the Etag value. If the Rack::Cache check that this Etag doesn’t matched the Etag value in the cache, it means that it has been expired. So will request for new contents and will pass back the new Etag as well. If the Etag match, then the content is still fresh, so will return only a 304 Not Modified response status instead of full contents. Thus it reduced transaction data. In case you are wondering how did Radiant keep the Etag data. Take a look at the following code snippet from Radiant:

 

def self.new(app, options={})
      self.use_x_sendfile = options.delete(:use_x_sendfile) if options[:use_x_sendfile]
      self.use_x_accel_redirect = options.delete(:use_x_accel_redirect) if options[:use_x_accel_redirect]
      Rack::Cache.new(app, {
          :entitystore => "radiant:tmp/cache/entity",
          :metastore => "radiant:tmp/cache/meta",
          :verbose => false,
          :allow_reload => false,
          :allow_revalidate => false}.merge(options))
end

So you can see that actually be default the cache is under your project_directory/tmp/cache/. However, metastore is accessed quite often since it is used to check if the entity is fresh of stale. So if we still use file system, it is going to be quite slow. In order to improve the speed of reading metastore. We can use MemCache to store metastore.

$cache = Memcache.new config.middleware.use Rack::Cache, :metastore => $cache, :entitystore => 'file:tmp/cache/entity'

However since the Rack::Cache is browser cache, so it is far from enough for Radiant. Every time a user loads a page for the first time, it will always be slow. Only subsequent request becomes fast. Radiant should implement some server side caching to improve the performance.

Read more at Rack Cache on Heroku With Memcache You may also want to ready HTTP/1.1: Caching in HTTP.

Radiant is a ruby on rails CMS. I am exploring it these few days. It is a really no fluff CMS. The core itself is thin. Most of the heavy jobs are designed to be done through the extensions system. However, it means that this kind of CMS must definitely need a lot of developers’ support and contribution. So one of the problem I found out is that a lot of extensions in the Radiant CMS are out of date. They are last updated at one or two years ago and only support older version of Radiant CMS 0.8. This is a bit terrible, as this CMS relies a lot on extensions. On the other hand, there is one more poplar ruby on rails CMS called Refinery. This CMS has better or more functionalities in the core. Meaning the first time you installed this CMS, without installing anything else, you will get more functions. However, I didn’t really try out Refinery so I can’t say it has any other pros and cons.

Ok, I have been talking too much. This article is about installing Radiant CMS extensions on windows. In order to install extensions for Radiant, you have to make sure you have to git installed. Then to install any extensions becomes easy:

ruby script/extension install extension_name

However, if you don’t have git installed, then it can’t connect to the repository and won’t be able to download extensions. So in order to user normal http instead of git, there is one extension for Radiant CMS called ‘Ray’. It’s meant to make the installation of Radiant Extensions easy. However, since you don’t have git installed, then how are you going to install this ‘Ray’ extension first, which helps you install extension. Sounds like a chicken and egg problem=) Ok, no worries, you don’t really need to use command to install extensions. You can install them manually as well. Go to the git repo page for Ray https://github.com/johnmuhl/radiant-ray-extension and download the files. Now extract the folder and rename it ‘ray’. If you open this folder, you should find ray_extension.rb. The ray before _extension is the name of the extension and the folder name must strictly follows this name.

Now you have Ray installed. If you do the following which is trying to installing an extension named meta

rake ray:extension:install name=meta

By right, it should still be able to download the extension although there is no git installed in your machine, However, it failed! It gives me very wired error messages that I forget what it is. Anyway, if it happens. I think then it is best that we just get git installed. Anyway git is a useful tool for developers. Go to http://code.google.com/p/msysgit/downloads/list page and install the git for windows. I think you must use the full installer http://code.google.com/p/msysgit/downloads/detail?name=Git-1.7.4-preview20110204.exe&can=2&q=

After that the git bash would be installed in your machine, launched it. Now you can use unix commands now! And git is installed as well. Now you can forget about ‘Ray’ and directly use Radiant way of installing extensions. However, when I try to create Radiant extensions in windows, I saw another problem. Saying that directory difference error. It points out that Radiant is installed in C drive, but the project I am creating is in D drive. This is weird. So I copy the project over to drive C then regenerate the extension. This time, it works!

ruby script/generate extension extension_name

Read the rest of this entry »