Designing a CMS Architecture
When faced with the alternative between an off-the-shelf CMS or a custom development, many companies pick solutions like ezPublish or Drupal. In addition to being free, these CMS seem to fulfill all possible requirements. But while choosing an open-source solution is a great idea, going for a full-featured CMS may prove more expensive than designing and developing your own Custom Management System.
Hidden Costs
What does it cost to integrate and deploy a website based on an open-source CMS? At first sight, not much. As for every CMS, you have to design your own templates and fill your website with initial data. But there are additional costs that pop up as soon as you need a little more than just plain content management.
Think about adding a blog or a forum to a website managed by a CMS. There are modules or plugins for that, but they never provide the same flexibility as plain blogging engines such as Wordpress, or plain forum engines like phpBB. So even if the basic requirement is fulfilled by a module, you will always need - always - to adapt its code.
And this is where it gets ugly. The code base of open source CMS engines and their plugin is nowhere as good as what you can see in RAD frameworks these days. Most of them are based on a very old architecture (PHP4, no object orientation, no proper error handling, direct access to the database, etc.). That means that changing something will be very painful, and very expensive. You will encounter numerous bugs, change the blogging plugin three times because neither of the ones you tested are capable of doing what you need, you will upgrade your CMS to the latest version to benefit from this single bug fix that should save your life but then you need to change all your existing configuration…
This is as bad as it sounds. Start changing one single line of code in an application build on top of Drupal or ezPublish, to name only the two major ones, and you are in trouble. The moment you need something that is not natively supported, you enter the Dark Zone of CMS hell. You are going to spend a lot of money on development. You will never see the end of the tunnel. That is, until someone says, a few years from now, “Do we need all that crap? Let’s build something that fits our needs and that actually works”.
Making Your Own CMS
Given number of available open-source CMS solutions, building one on your own sounds like a stupid idea. But if your website is 50% content management and 50% something else, you probably need to start with a web application framework like symfony or Django, rather than a CMS. These frameworks provide plugins that do part of the Content Management job already, so creating a CMS today is like assembling Lego bricks to build something that exactly fits your needs.
Take symfony, for instance. It provides native support, or support through plugins, for:
- Pretty URLs
- Generated forms and administration
- Caching
- Complex templates
- Multiple environments
- Sections organized in a tree structure
- User authentication, groups and permissions
- Search and indexing
- Image and other assets management
- Content tags and tag clouds
- User comments
- Moderation for user contributions
- Content history and versionning
- RSS feeds
- Tasks management and job queues
- Usage statistics
- Forum
- Blog
Symfony doesn’t yet provide an Access Control List or a Workflow plugin, but you can already put all of the above together and have a pretty powerful CMS engine.
A tailor-made CMS will always have less code and show better performance than any of the existing full-featured solutions. Also, you will be able to tweak it completely, since all the components are decoupled, and built with extensibility in mind.
Your custom CMS will cost you more during the first year, but if you expect your website(s) to live longer than that, then the benefit will become obvious after a year and a half. Plugging the CMS features into other parts of the website, adding features unrelated to content management, scaling to a larger audience, replacing the database engine or the caching backend, all that will be painless.
That is, if you design your custom CMS carefully, and with the future in mind.
Environments
When you add features to an application, you need a testing environment - a place where you can check that the additions work and don’t kill the rest of the application. That means that developers have a version of the website on their desktop computer, where they change stuff. Then, they upload the application to a test server, check that everything is OK, and only then can they deploy the application to the production server. This is a very common practice, often backed up by source version control and continuous integration tools.
But what happens when a new feature is not made of code, but of data? In ezPublish, for instance, in order to define a new type of content (they call it a “Class”), you have to use the backend web interface and fill in a few forms. The properties of the new type of content are stored in the database. In order to deploy this new type of content from the testing environment to the production environment, the developers need to transfer data from one database to another - without wiping off unrelated information on the production database, such as user comments, statistics, etc.
Deploying new features in this context means executing some SQL code on each server. This is much more dangerous than just pushing a new version of the codebase, especially when the data model is made of many tables glued together in complex joins. That’s why, in many websites based on ezPublish, developers add features directly on the production environment, or repeat the configuration using the backend interface on every environment. This is either a high risk or a large waste of time.
Data, or Code?
This environment drawback tends to be a major influence over the choice of features a CMS should provide. For almost every CMS feature, you should wonder: Can the user do that through the backend interface, or do we need a programmer to add a new element? In other terms, is the feature made of data, or code?
Off-the-shelf CMS engines will almost always answer ‘Data’. My personal opinion is that it is wrong in many cases. Content types are just one example, but think about workflows or page layouts for instance. They define a complex logic that always translates to code, and giving the user the ability to change them via a backend interface means storing code in the database and evaluating it at runtime. Then you can’t use op-code cache engines like APC incriease your website performance. And deploying that to production is a nightmare.
Some companies think that most of the CMS features should be accessible via a backend interface in order to be able to enhance the application without additional developments. But this is an illusion. For one, the configuration of content classes in ezPublish is so complex that it does indeed require a PHP developer, and an expensive one, since experience with ezPublish is one of the most demanded skills in the IT market (at least in France). More features mean more development, and there is no CMS out there that replaces the power of a programming language with a web interface.
So that leads to one good rule of thumb: Design your features so that they can be made of code rather than data. That applies to elements that can be modified by a graphical user interface, or programatically:
- Content classes
- “Widgets” or “Components” for pages
- Page layouts or “templates”
- Content validation workflow
- Tasks
Fundamental questions
The complexity of a CMS engine depends greatly on the answer you give to a few fundamental questions:
- Can contents exist independently of a page?
- Can contents exist at more than one place in the website?
- Are there several views for a single piece of content?
- Can contents have different versions simultaneously?
- Can contents be modified in the backend and keep unchanged in the frontend?
- Can users compose a page with “widgets” or “components” in a WYSIWYG interface?
- Can predefined zones in a template contain more than one “widget” or “component”?
- Can section pages have different templates?
- Can section pages have different versions simultaneously?
- Can users program the publishing of a section page, or of contents, in advance?
- Can the CMS remember previous URLs for a content that changed title?
If the answer to the first question is no, then the concept of “page” and “content” coincide. You probably don’t need to develop anything, since your CMS will be quite simple.
If you answer yes to all these questions, then the CMS might take three times longer to develop than what it would be otherwise.
That’s why the idea of a tailor-made CMS is not that stupid. No existing CMS will be able to answer these questions in every possible way. But designing your own relational schema based on the answer to these questions makes sense, economically speaking. Don’t make it complex if you don’t need do, or, to put it otherwise, Keep It Simple, Stupid.
Bootstrapping the reflection
Now that you’re trying to imagine what you actually need for your own CMS, here is a glimpse of the kind of technical challenge you will face all the time.
The question turns around the concept of content types. In a CMS, you mostly deal with “articles”. This type of content has a title, an author, a summary, a body, and a few other attributes. But you probably also need to deal with some other content types, like movies, slide shows, quiz games, polls, or recipes. These content types are defined by properties distinct from that of an article. Some of them can fit in a single structure, others require several structures related to each other. For instance, quiz games require a structure for the quiz itself, one for the questions, one for the answers to each question, and one for the quiz results.
The question is: Do you store the data for all these content types in a single table, or do you create a table for each content type? The most “normalized” choice is probably to create one data structure for each. You could have an “article” table, a “recipe” table, and even a “quiz” table with foreign keys to a “quiz_question” and a “quiz_result” table. That would allow you to make queries on some specific attributes of a specific content type. You could build a custom search engine for your recipes and look for ingredients, foreign cuisine and preparation time.
But then, if each content type has its own table(s), what do you do when you have to list all the contents of a section, or worse (that happens in the backend) all the contents of the website? Does that mean that, in order to display a list of contents, you must query several tables and aggregate the results together? This solution simply doesn’t scale, and a CMS built like that will become slower and slower as you add new content types.
So that probably means that you should store a reference to each content in a separate table, with a copy of the data that is generic to all content types (like title, publication date, section, etc.). Pages displaying a list of contents would use this aggregate table, while pages displaying content details would use the specific tables.
And that means that you must find a way to synchronize the specific tables and the generic tables whenever data changes in content. That’s not a big deal, but it gives you an idea of the kind of complexity you will encounter in a large scale CMS.
A Challenging Exercise
Designing a CMS is difficult and fun, and you’ll probably do it more than once. Every CMS is different, because every content management need is different, and mostly because every customer wants more than just plain content management.
If you are a developer, whenever you meet a client that asks you for a Drupal integration, try to sell your knowledge of CMS architectures rather than a few hours of developer time. Raise the important questions, talk about the possible problems of using off-the-shelf solutions. If you ever used one of those before, you will have plenty of issues to talk about. Then, try to convince your customer to trust you into a custom development. Make it small at the beginning, so that the customer can start using it right away and refine its requirements incrementally.
This will be a very satisfying experience, and the client will thank you later for leading him on the right path. And this will give you a lot to talk about for the next CMS you build…
Possibly related posts (automatically generated):
such a great article and it brings up a lot of things everyone should think about when developing software, not even a cms system… thanks a lot.
Really good analysis of the real challenge you get when your customer ask you to make a CMS solution…
Good work - can you get it finished by next week please? k tnx
I fully agree with you. To me CMSs want to adapt needs to their platform, while customers want a tool capable of adapting to their needs.
Frameworks are a great solution in this regard, because you can easily fulfill the real needs as they come.
excellent point made!
i had many problems with OS CMS systems ( have used Mambo/Joomla and Drupal), and when symfony came i abandoned all this ( including my custom framework )
for years now i was constantly trying to make my own CMS, but i just cannot make it “universal” enough.
So i gave up and continued with custom tailored solutions to each project/customer . and this makes my life a lot easier ( and i learn alot in between :))
You should see how Drupal answers these problems. Check out the cck module(for creating custom content types), the views module(for setting up and outputting content-think visual query builder), the panels module (for building custom layouts).
Each module provides a GUI for configuring your content types, setting up your views, laying out your content.
You also have the option to store the views and layouts in the database or in a template file. Storing the code in a template allows for easier version control.
Anyways here is the links: http://drupal.org/project/cck http://drupal.org/project/views http://drupal.org/project/panels
I ‘ve read a lot of discussions about this topic, and always a CMS solution is better for something and a framework for others…
Drupal is very ‘pluginable’ because it was think to extend it functionailty, and it is a good choice when you need to do a fast job. The hook system and the dependency between modules are very useful to make a new module and to change the functionality from an existing one.
I’m not in favor of CMS or framework. I just think choosing between one or other depends on the job.
Here some comments about your post:
@Francois: you will encounter numerous bugs, change the blogging plugin three times because neither of the ones you tested are capable of doing what you need, you will upgrade your CMS to the latest version to benefit from this single bug fix that should save your life but then you need to change all your existing configuration…
Does not happens with the upgrade from sf1.0 to sf1.1 or sf1.2???
@Francois:If you are a developer, whenever you meet a client that asks you for a Drupal integration, try to sell your knowledge of CMS architectures rather than a few hours of developer time
You probably know the client need sometimes a backend side to administrate this web site and this is pretty done in some CMS like Drupal. Besides some times we need to do that job really quick. Althougt the client want his site and doesn’t matter(in most of cases) the way you will do that job. He wants results, not to know if you use Drupal or Sf.
Well i think this dicussion could be very long but, as i said before there are a lot of discussions on the web about choosing one or another.
@saganxis: I think we agree that a CMS solution is perfect for a pure CMS requirement. My point is, most websites start being 90% CMS and 10% something else, and after a year or two they are 50% CMS and 50% something else. Building on top of a CMS is much harder than building on top of a framework. Choosing an existing CMS engine is a short-term view, and will not pay in the future.
As with upgrades, there is pretty much nothing you can’t do with symfony 1.0. Symfony provides the bricks, not the features. Drupal provides the features, that’s why upgrading is more critical than for symfony.
Regarding Drupal’s CCK and Views, which one commenter brought up, they do provide flexibility but the performance is really bad and not suitable for a complex, high traffic high availability site. How do I know? Because I built one with Drupal, CCK and Views and had to quickly scrap it and write my own Drupal modules and custom caching. Even then, I had to hack so more core Drupal code (since nothing is OO) that it became very difficult to maintain. There are just too many things in Drupal that you can’t do without hacking the core.
After recently finding Symfony I decided to rewrite the entire site. Crazy, maybe, but Symfony is everything that Drupal is not - beautifully designed, well thought out, easy to extend and modify, etc. Drupal might be great for non-developers who want to take advantage of all the great modules available, but Symfony is a real framework for real developers.
Just my opinion.
Or did you ever try typo3 (http://www.typo3.org)?
It offers a lot of flexibility regarding to content types. One can make custom modules or plugins (that can also be used as content elements on pages) and can hook into a lot of business logic.
Some of the things found there are a lill cumbersome sometimes but there are a lot of extensions (http://typo3.org/extensions) that can provide a nice base for your site or even for your own plugins.
Speaking about the quality of the codebase. Within this CMS they are overhauling the whole system right now but I can’t say that the foundation of this system isn’t solid. It’s widely used too actually.
Well I agree that rolling your own CMS could be a solution under certain conditions or if you have special needs regarding speed or flexibility.
But try to look at all options though.
Good article~But I am recently planning to design a new cms with the idea of web-service to address the problems you mentioned above. It is supposed to be a light-weight cms framewok with some modules that are often used.
Any one interested can send mail to bluefly#gmail dot com to contact me~
I appreciate your article on an important topic not yet resolved by CMS systems. However, while I completely agree to your thoughts on the 50% of functionality contained in websites, it seems to me that the key need for the 50% CMS (with more or less no functional data) tend to get forgotten.
A key requirement for so many websites (and thus the business case for CMS) is to allow non-programming web admins to manage and enhance their static information on the web site by themselfs (change existing contents, add new content by adding more web pages). Also if e.g. some more menu items be added, they want not be forced to call any programmer.
The core framework of symfony doesn’t have an answer for the mentioned need… however I currently see CMS-related plugins appearing these months, and even a dedicated project (steerCMS?). I haven’t checked their feature sets and maturity in detail, but could imagine that they (or one of them) become a potential solution for both sort of needs?
Once more, this is a great article I enjoyed to read fully. Thanks for it
Glenn mention about CCK, Views and Panels modules for Drupal. I’m now working with project where we are usign those modules and I have to say that they are quite complex to understand at least when they all are used together. So in complex projects Symfony will get my vote. And yes I’ve used both Drupal and Symfony.
What do you think about Steer CMS and the general idea of converting some of these large PHP apps to the Symfony PHP framework?
I’d love to see alot of Drupal/Joomla refactored into a plugin.
Also I agree about the workflow plugin, If anyone wants help on one, or a team is being formed, I’d like to participate on getting that done. I think the new admin generator / crud generator stuff in 1.2 will go a long way
Your argument applies equally to “shopping cart”, “blog”, and “gallery” systems, like OSCommerce/ZenCart, WordPress, and Gallery. I’ve used several amazing open-source apps like those written in variously old non-RAD PHP, but whenever I need to customize them I risk breaking them in the future, and I hate how crufty and non-modular they are when I dive into the code.
One HUGE advantage though of not starting from scratch is that while you’re doing other things like sleeping and eating, people are still developing your CMS/cart/blog/gallery, so in theory you can upgrade to the latest.
I guess porting/imitating some of those amazing apps to living symfony plugin projects would be a good blend of the two, but that sounds like a LOT of work. But how far do they need to be integrated?
Maybe someone should define a higher level REST architecture or something that all PHP apps and frameworks could support? In most cases you only need to integrate various apps at the View level– so if I could display WordPress posts and Gallery photos within a partial or component, it would be good enough, right? I guess all we’d need is for each app to support some RESTful URLs with nice undecorated data.
Something like this in my View-level component:
include_url('/wordpress/posts/index/latest/10');Or even better, they could output serialized (PHP or even JavaScript?) objects or something, which takes us into mashupland.
$posts = include_serialized_data('/wordpress/posts/index/latest/10'); foreach ($posts) {This topic is on a lot of designers’/developers’ minds. I started my own discussion here…
http://www.designicu.com/blog/cms-or-frameworks/
…and got some interesting replies.
As a designer who knows how to skin WordPress and Drupal, I do feel stuck with whatever a CMS can offer, or can be twisted to offer, but at the same time I don’t want to get into development-from-scratch (not my bag) or long-term support/debugging (definitely not my bag). There are benefits to both approaches, and sometimes a client’s budget is the limiting factor. Who wouldn’t want to whip up their own super-flexible CMS? But that kind of commitment is not on the cards for a lot of clients.
Never underestimate:
http://www.cushycms.com
You stole the words right out of my mouth.
Although some make arguments for Drupal and Joomla as being very extendable, from my experience in the wild (real websites not theory) these sites have been or will be hacked by several different programmers or entities. Even small changes get very buggy quick. We just got in a Joomla site that some programmer mangled so bad we turned down the site maintenance.
In my experience with frameworks, I was able to pick up a site that I have never touched and got right to work and knew where everything was.
interesting post, but I want to answer with eZ Publish in mind :
your paragraph on “Environments” is wrong for eZ Publish, it provides a package management tool which is useful to solve this problem.
“Start changing one single line of code in an application build on top of Drupal or ezPublish, to name only the two major ones, and you are in trouble. The moment you need something that is not natively supported, you enter the Dark Zone of CMS hell. You are going to spend a lot of money on development.” the same goes with any framework !
for the “Data, or Code?” paragraph it really depends on your client need that’s all, but with real flexible CMS you’re not obliged to adopte one or another…
How can you write “Designing a CMS is difficult and fun, and you’ll probably do it more than once.” and say that it will (always?) be cheaper ! I think you also forgot to mention that if you write your own CMS, you’ll have to maintain it which can be really difficult, I really prefer using a well tested product that has proved his quality and has been developed for years than my own code…
[...] Continue reading Posted by Federico Filed in Frameworks, PHP, Programming, Software Architecture [...]
I think everyone here is forgetting about ExpressionEngine, which is (92% of the time) the answer to pretty much every problem with CMSs out there. Just my 2 cents!
-1. Let’s carry this argument to its logical conclusion.
You don’t want to use an off-the-shelf OSS CMS because of the compromises you’ll have to make, and the development needed to make it behave as you need it to. So, you should use a framework instead, and develop a new CMS on top.
But you shouldn’t use an existing framework either, because of the compromises you’ll have to endure. So, build your own framework.
But, wait. The language you use to build the framework will include compromises you’ll have to code around. Dang it, now you need to create your own language, then make the framework, and then the CMS.
Hold on there. The assembly language you use to write your language interpreter or compiler will have compromises in it….
(I haven’t even mentioned editors, operating systems, file systems, or windows managers yet.)
There’s a reason why standing on the shoulders of giants, and building on others’ work, is a widely recognized good thing.
“Tailor-made”, not “taylor-made”. The expression refers to the custom fit which only an article of clothing made by a tailor can provide. Other than that, interesting article.
@Jay: Thanks, fixed.
Nice article.
FYI. In Ruby (and Rails) there is a CMS called RadiantCMS. It’s very barebones, but powerful and it is built on Rails.
I work in corporate environments using Documentum and Oracle. About 3 years ago when I started using Drupal and Joomla for side projects. Compared to Oracle they are much more lightweight! But overtime I have realized they can be more complex than necessary.
@John DeRosa: Right, compromises. I never thought about that. Obviously, I’m reinventing the wheel here. You’ve convinced me: I should always use a CMS. Always. Consider this post irrelevant, and thanks a lot for enlightning me.
Also, I think I should call you “Mister”, because you’re the first person I know who talks about himself at the third person.
@Francois: Wrong. You’re referring to someone else with the same name, not to me. Try clicking on my name if you want to read my blog.
Very interesting. You mention eZ Publish and what eZ is doing with reengineering their CMS with eZ Components is interesting too.
It seems that it will be possible to use only some components like the workflow components or more. As you say it can be a way to build you own app not necessarily 100% CMS.
Interesting post that mostly summarize most of my experience with both overly-TTW-flexible CMS like Plone, CPS, Drupal… and even with less flexible ones trying to grow plugin systems (Spip anyone ?).
wrt/ the first category, yeps, the conclusion is that you end up needing a real developer anyway - all this being way to complicated for the average webmaster -, and then the ‘flexibility’ finally become useless complexity that makes development longer and harder, not to talk about version control, testing and deployment issues.
Simpler apps like Spip suffer less of this problematic, but have their own warts too, mostly (when it comes to Spip at least) antiquated, rigid and undocumented code base, that makes writing any even trivial content-type plugin a real pain when compared to what frameworks like Django have to offer. IOW : Spip is fine as long as you don’t need more than what it has to offer - but as soon as you need custom content types, you start wasting development time, even if you already have a good knowledge of the inner working of the beast.
[...] Designing a CMS architecture - “This author spells out why he feels it’s important to create your own CMS and explains step by step how to plan it and why to give your clients the best CMS for their needs. “ [...]
[...] recent post from Francois Zaninotto has been getting a lot of attention recently. It’s his look at what [...]
[...] Designing a CMS Architecture [...]
[...] Designing a CMS Architecture Makes some good points in favor of building one’s own CMS. [...]
[...] così che François Zaninotto introduce un suo post molto interessante su un argomento dibattuto spesso dagli sviluppatori e che forse non avrà mai [...]