One of the primary functions of a web content management system is separating content from layout. Authors create semi-structured content in a display-neutral format and then the presentation templates transform that content to web pages for regular browsers, mobile browsers, RSS feeds, email, and print. As most readers of this blog know, this separation introduces big efficiencies in re-use: content is managed in one place and appears in many places and in many formats. But this magic does not come for free. Someone has to build presentation templates that render the content and that person needs to have developer skills. The template developer needs to know HTML and the special templating syntax to retrieve and format content from the repository. The developer also needs know how to test software for all the different conditions that it will encounter: different browsers; content with extreme values in any of its elements (like a really long title or a missing summary); and even high traffic load. Because one piece of code can potentially affect every page on the site, testing is important and it needs to be done in a safe place. The same thing goes for all sorts of other software configurations.
Essentially, the role of the static webmaster has been broken into two: the content contributors (that no longer need to be technical) and the developer (who needs to be more skilled than your average DreamWeaver jockey). It also breaks up the management of the site into two lifecycles: the content lifecycle and the code/configuration lifecycle. The production instance of the CMS itself is designed to support the content lifecycle. CMS have workflow functionality to manage the state of an asset from draft through published and to archived. They have preview functionality so that only contributors can see content that has not been published. Some CMS are designed sot that the development lifecycle can also occur in the production instance. This is usually done by creating workspaces or sandboxes — essentially treating code like another category of content. To be sure, you still want to have a QA instance of the system so you can test software upgrades (of the core) before applying them to your live site. In most CMS, however, developers work on separate environments (either individual developer environments and a code staging area or a shared development environment) and not the live, productive instance of the CMS.
While the content and the software lifecycles are de-coupled, they are interdependent. Developers need realistic content to develop and test code. The content relies on the code to define and display itself. There are lots of situations where these aspects get tangled. For example, when a new field is added to a content type it needs to be populated (sometimes manually) and the presentation templates need to be modified to display it. There are also cases where the line between content and code starts to blur: contributors style their content with CSS classes that are defined in style sheets; contributors can embed a tag that calls some additional display logic (like inserting a re-usable display component); contributors can build web forms that need to be submitted to code that does something with the information.

The standard approach for managing these interdependencies is what I call “code forward, content backward.” Content and configuration is developed in a development environment and tested in a QA environment. When it is ready, it is deployed to production. Content is developed and previewed in the production instance that contains the staging (or preview) and live content states. Periodically, content should be published backwards to the development and QA instances so that testing can be realistic as possible. In cases where the code/configuration and content are so tightly coupled (like when you need to break one field into two), you may need to export production content to the QA instance where you do some content transformation and test it with the newest code and then push that content and code back to production at the same time. When you do this, just make sure that you don’t have anyone adding content to production because it will be overwritten or (worse) cause some kind of corruption.
Different CMS handle the migration of code and content in different ways. Some provide nice graphical utilities to export configurations from instance of the application to another. In other products, there are ways to manually transfer the settings as a collection of files. Some products don’t support this at all so you have to manually repeat the same steps on each environment you are managing. When you are evaluating CMS products, keep these requirements in mind. Otherwise, you will be in for a surprise as you near the launch date of your new website and you need to fix bugs on live content.
Related posts:
- CMS Architecture: Managing Content Type Configurations Warning: this post is highly technical. Non-programmers, please avert your...
- CMS Architecture: Managing Presentation Templates Another geeky post… In my last post, I described the...
- Finally, Drupal Gets Deployment Greg Dunlap, over at Palantir, has a post introducing a...
- A test framework added to core of Drupal 7 Dries reports on a 2 day sprint in Paris where...
- Bricolage gets big boost from Google Summer of Code David Wheeler from the Bricolage project just posted the results...


This model works well when code and content are managed independently, but breaks down if the CMS is used to manage both. I don’t advocate a blended model (the “C” in CMS stands for “Content” after all, not “Code”), but it’s a strong meme, particularly in the ecosystems of certain specific CMS vendors.
[...] Gottlieb has written a great post entitled “Code moves forward. Content moves backward.” that, by strange coincidence, echoes an Alfresco KB item authored by Alfresco’s very [...]
Pingback: http://blogs.alfresco.com/wp/pmonks/2009/07/01/code-movement-vs-content-movement/
Really interesting one, i much appreciate. Thanks for sharing the information.
Nice post Seth. For management purposes, treating code and configuration as content, keeps things real simple. Backup the production instance, without taking it down, and you have everything in one place to be restored at your leisure for troubleshooting, snapshots, scaling, etc…
I tend to roll code forward and live content backward to meet in the staging environment. Customer signs off and then roll forward into live. For test and qa environment, same deal but the content from live may be slightly more out of date. But that’s okay.
Nice post Seth. I’m definitely going to bookmark this one as I come across customers asking about this same scenario.
One comment though. “Because one piece of code can potentially affect every page on the site.” Can’t you say the same about content? A reused piece of content can screw up a site just as bad if not worse than a piece of code. Say it is a marketing piece of content giving certain type of customer 80% off of on a widget and the publisher flagged the content for consumption by all users. Oops. I think that content should move forward like code, however, it is technically a different type of solution, i.e. bpm and ECI not ant deployments.
Good point Travis. It really depends on the system. Most CMS provide pretty good tools for safely reviewing content on the production instance of the application. However, the ability to safely test templating code (and content type definitions, workflow definitions, etc.) on production varies widely from platform to platform. I agree that bad content can be dangerous. One of my prior clients is an online sports book and publishing the wrong odds can cost millions of dollars in seconds. An editor can also do something silly like put an unclosed object tag in a persistent content element (like a header) and make every page on the site go white. Inadvertent assignment of permissions on a piece of content can yield embarrassing results too. That said, I think there is a higher margin for error in code. Or, maybe its just my code
@cleve years back I worked on an ATG project where we had two production environments: one was live, the other standby. We copied live to standby, did our work on standby then pointed the routers so that the standby became our primary. Next upgrade we did the same thing the other way around. This worked pretty well but you definitely had a fixed window to do your work because the system was essentially locked down from the copy to when you repointed.
Great post. Ironically, it’s almost exactly the same words I used in my book (Professional Plone Development) talking about this concept in the context of managing a real-world Plone project.
[...] Gottlieb has written a great post entitled “Code moves forward. Content moves backward.” that, by strange coincidence, echoes an Alfresco KB item authored by Alfresco’s very own Ben [...]