At a recent consulting, I was asked whether certain features can be implemented on a Joomla site. While some of these features were critical to them, most were subtle. After initial inspection, I concluded that though may be done on the Joomla platform, it would not worth the effort:
  1. While powerful, Joomla (and other well-know CMS platforms) are too heavy for my client's purpose. And their custom needs and planned business logics are hard to implement on a platform that focuses on content management.
  2. Thanks to the inexperienced previous maintainer. The structure of the original website was very messy. Which made it exponentially difficult on further development.
  3. The website response time was already a dismal, for the above two reasons.
  4. Testing is impossible - at least I don't know exactly how.
  5. All right, my bias against php may have contributed, too.

I don't usually suggest "rebuild from the ground up" since it is time-consuming and unnecessary most of the time. However, this looked like a perfectly legitimate case. Because they picked the wrong solution to begin with. And the lack of maintenance certainly didn't help.

They accepted my advice surprisingly well. Turned out, they don't prefer a heavy CMS either. It's just they were not able to find a developer who can build their website by code. But they liked the visual design ("the theme") and wanted it kept.

So I took the job. This "full-site conversion from a CMS" thing was an interesting experience. And I think I should take down some notes as future references for myself and others who are new to Rails.

Test

Tip: Write tests upfront based on the original website. Then write the rest of the tests based on the client's needs. Make sure the details are clear and concise.

A Rubyist's convention is to get (at least some) tests in place upfront. And this is the good part of full-site conversions: you know exactly the expected behaviours of the website already. So most of the test code was no-brainer.

However, the new custom features that need to be implemented are not on the original website. This is the part has to be handled more carefully. In my case, the client's description was (as usual) vague and would need many clarifications. So a few face-to-face meetings were necessary.

Plug - Personally I am not a big fan of cucumber. Adding another layer to my workflow slows things down. In most cases, I just communicate with clients in plain English/Chinese and then transform the requirements into my specs. Cucumber may be a better fit in larger projects.

The meetings were very efficient. I guess it was because the client had the website for a while and knew what he wanted - unlike the clients who come for websites from scratch. In a short time, I had my specs ready.

Theme conversion

Tip: While ripping original styling files sounds easier, reality is often the opposite. Look at the code and think whether it is something that future you would want to deal with.

The visual part isn't normally the first thing I do when developing a website. But for a full-site conversion from CMS, I felt this is the right order because:

  • No visual designing process. The theme was already there.
  • This website (as most of the CMS sites) had may isolated static pages. Once the layouts and stylings were ready these pages could be done immediately. I didn't have to think about them afterwards.

There are two ways of doing it: you either rip the stylesheets and JavaScript files directly from the original website, or implement the theme all by yourself. For me it is depending on the quality of the original code. But more often than not, I find the styling code of a CMS site can be really nasty. In this particular case, there were stylesheets from the CMS base code, from the theme, from the plugins, and from the previous maintainer. A lot of dirty patches and redundant code were around. Various JavaScript files were included in every single page while were only used in one or two pages. I was kind of expecting this situation though. This was due to the very nature of a traditional CMS platform - "Everything is included and is only one mouse click away."

So I went ahead and implemented the theme from scratch. It wasn't a pixel to pixel match. My client was fine with that. An exact match was not impossible but would have taken much longer. I made a few UI improvements when implementing the theme as well.

Feature implementation

This is the routine part. To be honest it could be somewhat boring. CMS websites are not meant for complex business logics. So most of the time you will be dealing with simple CRUD stuff - rails g scaffold Whatever and spending most of your time on the view part.

I am just going to list some general tips I learnt here:

Tip: Use less gems. Gems can be very helpful. But dependency is a bxxxh.

You should not throw devise onto a project that only requires a simple register/login user system. Roll your own instead. Remember this: You need to wait until every gem you used is ready to carry out a major upgrade of your project.

Tip: Don't be afraid of the edge.

  • I knew Rails community is generally agile on fixing bugs.
  • Experiences taught me that to start from a certain major version is much less painful than to upgrade to this version later on.
  • From last tip: Few gems I used were locked in Rails 3. And I could finish without them. If there was a major gem did not support Rails 4, I would just have to compromise.
  • (This is just me) I could not stand not being at the edge :p

Tip: Offload static pages.

Typical CMS based websites often contain numerous static webpages that get visited a lot. Caching them is certainly a reasonable way. But I like the offloading approach more - move them out of the app directory and let nginx do the heavy lifting. The tricky point here is that in most cases the urls have to be maintained. Therefore spending some time learning the nginx rewrite rules is necessary.

Iteration

Tip: Don't be clever. Be disciplined.

Upon a new requirement - especially an easy one, I typically would want to rails g right away and implement it in an hour. And I did work like that before. Isn't that agile?

Sometimes it will just work. But TDD isn't anything like that. The red should before the implementation, hard or easy the feature is. Tests not only give you peace in mind later, but force you to think it through beforehand. For simple features that don't need specific design processes, writing tests serves as design.

Of course, there will be many tests being added after implementation. Just don't start with nothing in place at all.

Tip: Refactoring can wait.

Ship features first, refactor code later. Dirty working code is always better than clean non-functional code.

Ship

Tip: Keep the original website for a while.

Take the original website offline. But don't destroy it yet. Keep it for a month or so just in case.

Converting a standard CMS based website to Rails is not hard. Just pay attention to the details. Hope these general tips will help someone.