Working With a Content Management Framework: MODx

If you are interested in Content Management Systems (CMS) then most likely you have heard about MODx (modxcms.com). MODx is not just an extremely flexible CMS that makes managing website content a breeze, it is also a powerful Content Management Framework with an extensive API that makes it a developer's dream.

"MODx is an open source PHP Application Framework with Powerful Features that help you take control of your online content. It empowers developers and advanced users to give as much control as desired to whomever they desire for day-to-day website content maintenance chores."

In this tutorial we will explore a number of the standard MODx features to illustrate what it is like to work with MODx by going through the process of taking a static HTML prototype and turning it into a working MODx driven website. We will be covering a lot of territory in order to paint a big picture of what you can do with MODx but will only be skimming the surface of what is possible.

Our project will be based on a standard MODx install. You can download the latest MODx release from the MODx website.

In order to focus on the actual MODx development, we will be using the HTML from the Prototyping With The Grid 960 CSS Framework tutorial as our base HTML template. Any HTML file can become a MODx template with minimal effort. And incorporating a CSS framework to MODx is no problem. The basic concept is: if it works outside of MODx then it will work inside MODx. I made a few minor modifications to the HTML for this tutorial, as well as built a simple "content" page based on the home. These are the layout templates that we will be starting with:

Here is a roadmap of the key topics we will be covering:

The Groundwork: Before we start

The Manager: Templates and Documents

Placeholders: Dynamic content

Snippets: Adding smart navigation

Chunks: Reusable code

Template Variables: Custom fields on steroids

Hierarchy: Parents and Children

Ditto: Repurposing Content

Conclusion

The Groundwork: Before we start

The first step is to prepare the HTML files to be used as MODx templates by adjusting the file paths to reflect the final file structure we will be using. MODx provides the /assets/ folder for storing the site files and this is what we will follow. However, you are allowed to place the files anywhere you want. This is one of the features that makes MODx easy to integrate into your existing workflow.

I have uploaded the base images for the template in the existing /images/ folder, and then created a new folder named "css" where I uploaded the css files. At this time we are only concerned with the site structure and not worried about the content just yet. Therefore we only need to adjust the paths for the CSS files and the 'logo' image, the remaining content will be included via MODx.

We are not quite finished with the HTML documents. However, for the remainder of the process we can work within the realm of MODx.

The Manager: Templates and Documents

The MODx Manager is the administrative control panel. Login to the MODx Manager.

The Manager is basically comprised of 3 parts:

the Admin Menu located on the top;

the Document Tree is to the left; and the

Action/Edit Area is to the right and will change according to the selected function.

At this point we want to add our HTML files into the MODx environment as Templates. Select Resources > Manage Resource from the Admin Menu to the websites resources.

Select the Templates tab. Click on the 'New template' link to enter the Create/edit template screen. Set a name and a description for your template, and optionally add the template to a category to help keep your resources organized (we will use 960 as our category). Paste the HTML in to the text field labeled 'Template code (html)' and click on "Save"

Repeat the process with the content template. We should now have our 2 new templates as well as the Minimal Template that is packaged with MODx and created during the installation.

Next we will go ahead and create a few MODx documents (web pages) to represent our site's initial structure. Lets start by editing the existing document that was created during the installation. In the Document Tree (left hand column) right-click (control-click on the mac) on the document name to bring up the Contextual Menu. In the menu select the option 'Edit Document".

The 'Create/edit document' screen is now loaded in the main body of the manager and you are ready to edit the selected document. The document's data is grouped in sections according to function and content. At the top we have the Document Setting section which houses the pages parameters as well as the status information.

Next we have the Document Content section where the main content field for the document is managed. The content field has the option to include a RTE (Rich Text Editor).

Finally there is the Template Variable section. Template Variables are MODx's answer to Custom Content fields. And MODx does this very well. We will see them in action a little later.

OK, back to business. We can rename the existing document and make this be our Home page. To do this, while in edit mode type Home in the 'Title' field, then clear the text that is in the 'Long Title' field, and also clear the text that is in the 'Menu Title' field (we will not use these fields for this tutorial). Next, select the template that we created for the home page from the 'Uses Template' pull down menu (note; when changing templates you will receive a prompt warning you that the page will reload).

Once complete click on save and you will now see that the document in the Document Tree now reads 'Home'.

Next we will add the remaining top level content pages. Click on the 'New Document' icon in the tool bar directly above the Document Tree to create a new blank document at root level.

In the 'Title' field type in 'Articles' and select the 'Content' template we created earlier from the 'Uses template' menu. Since we are working on a new document it defaults to the up-published state (the defaults can be overridden in the site settings). So before we save it we need to set it to published by selecting the Page Settings tab and checking the Published option.

Before saving the document select the 'Add another' function (located just bellow the top save button). This will automatically cue up another document to be created after saving the current one. This is a great time saver when adding multiple documents.

Repeat this process for the remaining top level menu items; Articles, Topics, About, Editors, and Contact. When you finish your document tree will look like this (note: the number in parenthesis is the document's ID number, we will need to know this later):

Up to this point we have been laying the groundwork for our project and have seen very little of what MODx can do (although the easy way to set up a site is impressive). Lets do a quick recap:

We have 2 HTML templates;

we have uploaded the files to our modx installation;

and we have created a number of top level documents or 'web pages'.

Believe me, it took way longer for you to read what we have done so far than it would take you to do it. A developer familiar with MODx could accomplish what we have done so far in about 10 minutes or less.

Things are about to get very interesting. Now that we have our basic site structure we can start working with MODx.

Placeholders: Dynamic Content

Now we will return to our templates and add placeholders for the dynamic content. As we previously saw while we created the new documents, MODx provides a number of fields that we can use as the basis for our content management. In MODx the group of data fields that are associated with every document are referred to as the 'Document Object' and the individual fields are the 'Document Variables'. Every field can be included dynamically to the MODx rendered output by means of placeholders. Placeholders for the Document Variables are identified by the following syntax: [*variable-Name*]. So if the want to add the Content field we would use [*content*] placeholder. MODx also provides placeholders for global Site Variables for data like the 'site url' or the 'site name', Site Variables are identified with the following syntax: [(var-Name)]. For example we can take the <title> and have it reflect the active page title and the site name by adding the corresponding placeholders. Here is our original title tag:

<title>Magazine 960 — Prototype</title>

And here it is after we add the placeholders:

<title>[*pagetitle*] — [(site_name)]</title>

And it will render as:

Our next step is to work with the 'content' template by adding the placeholders for the dynamic content. You can either open the template directly in the Manager or use an external code editor of your choice and paste code back into MODx when you are finished (note: you can also keep your template files as external 'include' files if you want, but we will not cover that in this tutorial).

In our template we will have dynamic content in the body of the site, the footer, and in the head section. Here is what the head section should look like after adding the placeholders:

Notice that I added the <base> tag with the [(site_url)] placeholder and also added the [(modx_charset)] placeholder to define the charset. MODx requires the base tag for relative urls. Note: the site_name and modx_charset are defined in the site configuration panel in the Manager.

For the general content section we will add the content and pagetitle placeholders:

Save the edited template file. If you preview one of the content pages of our site you will notice that the page <title> will reflect the title of page you are viewing.

Snippets: Adding smart navigation

Now we will be introduced to MODx snippets by using the Wayfinder snippet to include a working 'smart' navigation to our site. By smart I mean: the navigation will know when we add a new document and it should be aware of the current location within the site and apply the proper styles as well as manage the behavior when handling children documents. In MODx the most common method for creating navigation is with the 'Wayfinder' snippet. A Snippet in MODx is basically a PHP script that will be executed when the document is parsed. Adding a snippet to your document is virtually the same as embedding a PHP function into your web page. Snippets are written in standard PHP code so any coding enthusiast can easily create their own snippets. MODx also features a powerful API that is available within snippet code which makes interacting with the content database and other functions effortless.

Wayfinder will output the document structure and hierarchy according to the site structure in the Document Tree. By default Wayfinder displays the output as an unordered list with each document displayed as a list item and subsequent children as embedded <ul> lists. Sound familiar, this is the standard output for most modern CSS styled menus. However, Wayfinder allows you to personalize each part of the output by means of template chunks. In other words you can have almost any output you need by applying custom templates for Wayfinder to use. Also if you have multiple menus on the same page, each one can have it's own output templates.

Snippets are identified by the following syntax: [[Snippet-Name]] and can include additional parameters for processing: [[Snippet-Name? &param1=`value` &param2=`value`]]. MODx treats each parameter as an input variable and makes them available for use within the Snippet seamlessly. Snippets are not part of MODx, they are add-ons that function within MODx. Snippets are authored and maintained by the MODx community.

This is easy for Wayfinder and will not require a custom output template.

To add the dynamically generated menu to our template, replace the mock navigation above with the following Wayfinder call:

[[Wayfinder? &startId=`0` &level=`1`]]

The startId=`0` parameter indicates where the menu starts, and by setting it to 0 we are telling Wayfinder to get the top level menu. &level=`1` is telling Wayfinder to only go 1 level deep (no sub menus). After adding the Snippet call the template should look like this:

Preview a content document and you will see that the navigation is now active and the current page is styled in an 'active' state with class='active'.

You will also notice that the 'Home' page is also in the menu but we don't want it to be there. No problem. Edit the Home page (right-click on the home document in the document tree and select 'Edit Document'). In the 'General' tab in the Document Settings section you will see that the 'Show in menu' option is selected. Simply uncheck the box and save the document.

If you return to the site the Home link will no longer be visible.

Now our main navigation is complete in the 'content' template. Wait a minute! What about the home page? Do we need to repeat everything again for each template? The answer is: NO!

Chunks: Reusable code

A chunk in MODx is a bit of reusable HTML code (no PHP). Chunks can be used to store markup that is common in several documents. This is very handy when managing resources like templates that are made up of various common markup elements such as the header and footer of the site. In our example, where we only have 2 templates, this is not crucial. However, imagine having several templates and having to update a common element on each one. By using a chunk you will only need to edit it once and it will be rendered everywhere the chunk is called (and will be cached only once keeping the file size down). A chunk is identified by the following syntax: {{chunk-Name}}

Creating a chunk is much like creating a template. While in the Manager go to Resources > Manage Resources and select the Chunks tab.

Give the chunk a unique name and a description and place the HTML in the 'Chunk Code' field. We will be creating 2 chunks, one for the header and a second for the footer. In the header chunk we will include everything above the content area and name it "site-header".

Now we can apply the same chunks to the 'Home' template and carry over all of the work that we did with the content template. This will help us when updating the templates. Once complete you should now preview the site and be able to navigate between pages and the common elements should remain consistent throughout the site.

While previewing the site you may have noticed something missing. The design states that there will be an image on each page. However, there isn't a document variable for adding an image. Sure I can add images using the WYSIWYG editor if the image was part of the content. However, our image is in an isolated column away from the content field. You say to yourself: "If we only had a way to add custom content fields".

Template Variables: Custom fields on steroids

The concept of custom content fields is by no means new, and many CMS have implemented some sort of custom fields. The MODx solution are named Template Variables (or TV). These are custom fields that can be formated to specific output types, or can output programatically generated list, or can generate a data grid based on the result of a query... Basically there is a TV for whatever your needs may be. MODx makes sure that the custom data is at your fingertips and is seamlessly integrated with the standard document content.

The custom fields are attached to the document by association with the template the document is using (hence the name Template Variable). This allows you can create groups of TVs for specific sections of your site based on the templates that the pages are using. You can have one set of TVs for one section, and another set for another section, and still share common TVs when needed. Template Variables use the same syntax as Document Variables: [*Template-Variable-Name*]

We will be creating an Image type TV. An Image TV will generate a custom input field with access to the Resource Manager (MODx currently uses the MCPuk file manager) which includes the image browser as well as the ability to upload new images.

To create a new Template Variable, in the Manager go to Resources > Manage Resources and select the 'Template Variable' tab and click on the 'New Template Variable' link. Fill in the Variable Name field with a unique name. This name will be used to identify the TV as well as the placeholder. We will name our TV 'image' and will reference it with the [*image*] placeholder. The Caption field is used to give a friendly title that will be used as a label for the TV together with the Description field. For the Input Type we want to select the option Image from the pull down menu. Optionally we can use an output Widget to format the results when rendered in the front end. However, in our case we will not be using an output widget.

The final step is to assign the content variable to the templates we want to use it in by checking the box next to the template's name in the Template access section. For our project, only the content pages will have an image so we do not need to include the 'Home' template.

Optionally we can also limit the TV to specific user groups. This is very handy in using custom content that only administrators should be able to edit.

Save the TV and you should now see it listed with the sites resources.

Now if you edit a content document you will now have access to the Image TV we just created. Click on the 'insert' button that is attached to the field to upload an image or to select an image from the Resource Browser.

Once the image is selected in the Resource Browser it's path will be available in the input field and the image will be displayed directly in the Manager bellow the image field. Although MODx does not natively provide image manipulation features, there are several image resizing and thumbnail generating add-ons available that can work seamlessly with image TVs.

Next simply apply the image TV to the 'content' template by replacing the static image path with the placeholder for the Template Variable:

We are now finished with the overall format of the site. You can now add some text and images to the content pages if you want. Enter Edit mode by right-clicking on the document you want to edit in the Document Tree and selecting Edit Document. After adding some content and images the site is beginning to take shape. And if you look at the site you will notice it looks much like the original prototype (as it should).

Hierarchy: Parents and Children

To kick off this final stretch we need at least 5 articles to work with. We have seen how to create documents, nothing new here. However this time we will place the new documents as children of the existing 'Articles' document as if it was a folder. This is when the Document Tree becomes very useful, since it will give you a visual representation of the document's parent/child hierarchy.

Login to the Manager and in the Document Tree, right-click (control-click on mac) on the document titled 'Articles' to bring up the contextual menu. Select 'Create Document Here' from the menu options to open the Create/Edit Document screen.

Make sure that the document is set to use the 'content' template and proceed to fill in the content fields, including the image TV, and save the document.

If you now look at the Document Tree now you will notice a + next to the Articles document. This means that this document has children. Click on the + to expand and see the children documents.

Now create 4 more children by either repeating the process we just did, or by duplicating the existing document (tip: duplicating the document will save time since the content will also be duplicated). To duplicate a document select the document and choose 'Duplicate Document' from the contextual menu. The new document will be created at the same level as the original.

Once finished Articles document should have 5 children documents complete with content. If you preview an article document in the front-end you will notice that the main menu will reflect that these documents are children of the Articles menu item.

Ditto: Repurposing Content

Our final task in this tutorial will be to build the Home page. As with most magazine sites, the content that is displayed on the home page is extracted from pages within the site and not from the home page itself. Our design calls for 1 headline story and 4 secondary stories, and we want the headline to be the article that was created most recently (in a real-life scenario we would most likely use the published date). Also, we want this to be automated, so that the editor only needs to add the article and does not need to be concerned with the home page.

To accomplish this with MODx we will be using a snippet named Ditto (developed by Mark Kaplan). This is one of the most useful tools that you will see in any CMS environment. Ditto does so much, so well, that it is difficult to summarize what it can do. Basically it provides you a way to easily query the site content, then fine tune the results with multiple filters, while still giving the developer total control over the output structure of the results.

By looking at the home template we can identify that there are 2 different output displays we need to be work with. There is the top section with the headline article that also includes the image for the article. And there is a secondary section that has a summary of 4 recent articles but with no image:

As with most solutions in MODx, there are various approaches to accomplish our task. We could treat the headline and the secondary articles independently with individual Ditto calls, that would work fine. However, we will do it with one simple Ditto call and subsequently only one database query. Remember that Ditto is a snippet so it follows the snippet syntax which means we can define parameters in the snippet call to configure the snippet's action.

Edit the home template (good idea to make a backup first since we will need to reference the original markup later) and replace the entire content section with this Ditto call:

&parents=`2` tells Ditto to only return documents that are children of document ID 2;

&display=`5` tells Ditto to only display 5 articles

&orderBy=`createdon DESC` and this tells Ditto to sort the results by the 'createdon' field (which is the time-stamp for when the document was created) document variable in DESCending order (much like a SQL query).

Preview the home page and you will see the results of our query as a list of articles with some additional default information. You can experiment by changing the parameter values and see how the results will change accordingly.

We are getting the right results but the formating and content are not quite there. As we have mentioned previously when we talked about Wayfinder, Ditto also allows us to format the output to accommodate our needs by means of template chunks. We will now apply formating to our Ditto results.

As the name implies, Template Chunks are chunks, so we start by going to the Chunks tab in the Manage Resources section. Create a new chunk and give it a descriptive title like "home-articles". This will be the template chunk (or tpl) for the secondary articles.

We will be using the markup from the original home page template as the starting point for our tpl. Then we will replace the static text with dynamic content by means of placeholders. This is similar to adding placeholders to the site templates, however the placeholders are being returned from the Ditto query rather than from the active document.

Here is the original markup. Paste this as the content of our new chunk:

Preview the home page and it will show the articles as columns in descending order.

Notice that we are getting the entire article content, but all we want is the first part of the article truncated after a determined number of characters as a summary. No problem. We can simply add &extenders=`summary` to the Ditto call and use the [+summary+] placeholder rather than the [+content+] placeholder in the tpl chunk. An extender will extend the Ditto function for a specific purpose, like a plugin. In this case it adds the Summary function. The tpl chunk should now look like this:

The final step will be to style the most recent article and style it as the headline. Ditto provides us with a method for this by means of the tplFirst parameter which is used to give the first item returned a personalized display.

Create a new chunk and name it 'home-headline' and paste in the original markup for the headline section:

Save the chunk and append the Ditto call to include the &tplFirst=`home-headline` parameter which tells Ditto to use the `home-headline` chunk to format the first result returned. The final home page template, including the final Ditto call, will look like this:

Preview the home page and you should see something like the image bellow. Click on the 'Continue Reading' links and you should be taken to the article page with the full story.

The site is now functioning. With the information we have learned above you should be able to add some finishing touches on your own. Try using Ditto to create the 'Recent Article' list on the content pages, or add an Article index on the Articles page.

Conclusion

This tutorial was a bit ambitious. My objective was to illustrate how easy it is to work with MODx. And although I have introduced you to concepts like {{chunks}} [*document-variables*] and [[Snippets]], this only shows a tiny fraction of what MODx is about. I urge you to download and install MODx and give it a try for yourself. The MODx community is the driving force behind it's success and the community forum is very friendly and is a wealth of information, be sure to check it out.

Subscribe to the NETTUTS RSS Feed for more daily web development tuts and articles.