I’ve spent perhaps 20 hours looking into ModX Revolution, a “simple” content management system (CMS) that had been a runner-up in a recent Best Open Source CMS Award back in November 2009. The winner was WordPress, which I’m already familiar with. I flipped a coin and decided I’d look into using ModX as the base for implementing “easy to update” support for the $75.00 templates. How bad could it be? I was experienced making templates for both WordPress and ExpressionEngine (sort of), so picking up a new CMS should be relatively easy, right?
Well, not really. It’s super easy to deploy a new CMS, but mastering it is a function of how well the documentation and code examples clarify the architectural and workflow decisions of the CMS designers. ModX is above-average in the availability of documentation and an active user forum, but finding a clear, concise explanation of how it all fits together (beyond toy-like examples) is taking a long time. Plus it turned out I had downloaded the old version (called Evolution) of ModX, not the swanky new beta (called Revolution), so today I had to re-install and start from scratch. It is not documented that well yet, but I’m starting to get a handle on how the designers think about the CMS and I’m writing some notes here to help me retain those insights.
Why use a CMS and not something else?
The reason I want to use a Content Management System (CMS) is because I don’t expect the average client to want to edit HTML, and I don’t want to be the bottleneck when it comes to the client’s need to update something on their page. In the past, I’ve used Dreamweaver to set up templates and required the client to use either Dreamweaver or Contribute (the “client version” of Dreamweaver) to make updates to the plain HTML files that comprise their site. However, this is an expensive solution (minimum outlay: about a hundred bucks) and Dreamweaver/Contribute doesn’t deliver a great user experience. Web-based forms, on the other hand, have come a long way in the past five years, with Rich Text Editing capabilities rivaling those of simple word processors. WordPress is a good example of a nice CMS experience, though it is geared more toward blogging, and perhaps provides TOO much power.
A simple CMS would be easier for clients, and require no outlay of cash on their part. I just need to figure out how ModX work, because it’s kind of wacky compared to what I’ve used before.
My Mental Model of the Generic CMS
With a CMS-based website, you create a “template” that is mostly HTML and with some placeholder content. The placeholders are data (text, usually) that’s stored in a database, and when a web page is requested a new HTML page is created on-the-fly by the web server. The placeholders in the template are replaced with content in the database, and the resulting HTML document is sent to the requesting browser. The advantage of this approach is that the template is separated from the content, so you can change the content without having to rebuild the template every time. You can think of a template as a kind of like a picture frame; the placeholder photo of some other person’s kid gets replaced by you with a photo of whatever you want. What I want to do is sell that picture frame so it’s as easy as possible for you to change the photo yourself. If you instead had to return the frame to me, and have me open up the back and re-insert your picture, that would be a hassle for all involved.
CMSs are founded on the basic idea that a piece of text (which I’ll call “content”, as in the “content of a box” ) can be displayed through an intermediary called a template. A template is like a display frame that “holds” content so it can be properly displayed to the world. If you get tired of the way the template looks, you can make a new one and put your old content in it. In essence, a CMS provides the following capabilities:
- You can store multiple pieces of content in a database (usually text), each piece which has a unique identifier (e.g. a number).
- You can have multiple templates, each of which can display and style the same piece of content in a different ways.
- The combination of the template and content together create a complete web page. This is often called a dynamic page.
- Content can be inserted into a template at any place, if you know its unique identifier.
- You can change a piece of content to change a webpage, without having to change the template. This makes it easy to change what you can read on the website, without having to deal with the hairy HTML code that makes everything look right. The CMS takes care of this for you.
Nearly every CMS has some kind of programming language embedded in it, allowing the following special uses that are based on universal computer programming concepts:
- Content can be transformed before being inserted into the template through the use of programming.
- Pieces of content can be sorted by a number of criteria, such as the date it was created (useful for a blog).
- Pieces of content can be processed one at a time in a template, each inspected before being inserted into the template.
- Information that can be calculated can be transformed into HTML on the fly as well to create more dynamic websites.
- Templates can contain other templates. There is usually some explicit way of referring to one template from with another, and often there are times when the CMS will include the template without you having to explicitly declare anything.
- Content can contain other content. As with templates, content can refer to other pieces of content to be “included”.
- Content can come from places other than the database. It can be encoded onto the URL, requested through a webservice, calculated by a program in real-time, or stored as files on the web server host.
- Content can be turned into Template Code, which generates more content or even changes the way a template looks.
Theoretically, to create a CMS-based simple website I would merely need to do the following:
- Make a web page design in plain old HTML, with area designated to hold various kinds of content.
- Convert the HTML into the CMS’s templating language. Usually this is as simple as just inserting a “placeholder tag” where you want your content to appear; this will be replaced by a piece of content later.
- Create a URL for your webpage, and associate it with both a template and a piece of content.
How ModX Revolution Maps to the Generic CMS Model
Armed with these assumptions, the first order of business is to figure out where the templates are stored, find some documentation for the templating language, and then figure out how to enter your content into the system. A very basic CMS would just implement the basic ideas presented above, but in practice developers often want the ability to do more with fancy programming. ModX supports the basics and the advanced programming as well; the problem with the documentation is that is presents all the special pieces all at once without specifying the hierarchy of relationships. What I am looking for is how the basics work, and then understand how the special bits modify that. Additionally, the special pieces have names that do not indicate what they do; the difference between a “snippet” and a “chunk” is quite meaningful, but the terminology is ambiguous by itself. This is a good example of bad naming in in software design. The result is confusion.
So here’s how I understand ModX to work:
- The content on each page is stored in a data structure called a resource. In order documentation, it is also called a document as. It’s displayed in a tree structure called a “resource list” on the left-side of the manager interface. Each resource is essentially a web page. There are standard fields: title, long_title, description, and content. Additionally, each resource has an associated template with it. You also set the page’s URL in the resource. Everything to define a simple page except the HTML markup is stored in a resource, and each resource has an id. To actually display a web page, you need to pair the resource with a Template, which select from a dropdown menu.
- Templates are a subtype of element in the ModX nomencalture, and you have to create them from the element list. Templates can not only contain HTML: they can also contain other elements like Template Variables, Chunks, Snippets, and Plugins. Each element type has a corresponding special tag that can be embedded in the Template. For example, to embed a chunk named “foochunk”, you’d insert [[$foochunk]] in the Template’s HTML, whic will be replaced when the web page is viewed in a browser.
Now, the more advanced stuff:
- Each resource aka document has only one “content” field where a user can type in text. So what if you want more than just one area? You create a Template Variable, and then make it available it to specific Templates. Once you do that, when you go to edit a resource (i.e. a page), you edit the main content on the “create/edit” tab, then select the “template variables” tab to edit the rest of them. In essence, a Template Variable allows you to add additional field types to ModX. And if you think it works backwards from the way you think it should work, I am with you. Anyway, when you create a Template Variable you can specify how the data is formatted and spit out as HTML, which is pretty convenient in theory. I have yet to try it. I think you can also enter Chunk and Snippet tags apparently, though I have not tried it.
- For those times when you want to include static text or HTML in your template, you can create a Chunk. Chunks are actually parsed for tags, and their output is cached. Chunks can’t contain PHP, but they can contain references to Snippets and ModX Settings (e.g. things like the name of the website). Snippets are invoked from within a Chunk using a Placeholder syntax that can pass along some simple formatting codes. Snippets NEVER generate HTML, so the Chunk’s responsibility is to “wrap” snippet output.
- And when you want to include data-generating PHP code in the template, you can create a Snippet. From within a Template, Snippets are invoked using a kind of function-call syntax, with variables set within it in a way similar to (but not exactly like) the &var=`val` syntax seen on httpd GET-style forms pages. There is some kind of magic used to connect a Snippet to a Placeholder that I haven’t found clearly stated; it may be that all installed Snippets check for placeholders in the current Chunk.
So I think that’s how it works. The general philosophy behind the workflow is to create all your elements from the bottom up, then build your resource from those elements by linking to them.