DEVTRENCH.COM

MODx Evolution Templating Strategy

Note: This tutorial is for MODx Evolution and does not go into concepts for the latest version of MODx (Revolution). Hopefully I'll have time to write that in the future, but for now that is left as an exercise for the reader.

This tutorial has come about simply because I've worked on a lot of sites that aren't using the MODx templating system in an optimal manner for scaling websites. MODx gives you a lot of freedom and you can set up your Templates any way that you want, but I've developed a system that works great for scaling websites, and is easy to learn and use. In this tutorial I'll be using the word template (lowercase 't') to refer to the overall html template that you're putting into MODx. This template is what a CSS/XHTML developer would hand off to you. I'll be using the word Template (capital 'T') to refer specifically to to the Template tab on the MODx Resources/Elements page.

Typically what I see are Templates being set up like HTML pages with a doctype, full html head, lots of markup and template variables and document tags. This is what the MODx documentation recommends, author of 'MODx Web Development' recommends, as well as numerous blogs. In my opinion, this is wrong. A Template should simply act as a container for Chunks and that's it. My Templates are nothing more than this:

{{Head}}
<body>
{{Banner}}
{{Content}}
{{Footer}}
{{FooterCode}}
</body>
</html>

The strategy behind this is that you can create many Templates that use the same Chunks, and only switch out the parts that change. For instance, most of your templates will use the same Head, Banner, Footer and FooterCode Chunks, but all will have a different content Chunk. For example, the Template above may be the default Template for the inside pages while this Template is for the homepage:

{{Head}}
<body>
{{Banner}}
{{Content-Home}}
{{Footer}}
{{FooterCode}}
</body>
</html>

To make this strategy work best you need to understand each basic chunk and implement a few template variables.

The Chunks

{{Head}}
The Head Chunk contains the Doctype, opening HTML tag and the Head tag. It also contains all three special template variables that you'll need in order to make page specific customizations to the head. Here is an example Head Chunk:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <title>[\[Title]]</title>
 <base href="[(site_url)]" />
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <meta name="description" content="[\[DynamicDescription? &descriptionTV=`MetaDescription`]]" />
 <meta name="keywords" content="[*MetaKeywords*]" />
 <script type='text/javascript' src='assets/js/jquery-1.3.2.min.js'></script>
 <link rel='stylesheet' href='assets/templates/2009/css/mce.css' media='all' />
 <link rel='stylesheet' href='assets/templates/2009/css/site.css' media='all' />
 [*ExtraHeadScripts*]
 </head>

The head of your Template needs to be configurable in a few ways.

  1. The Title needs to different on every page. Here, I'm doing it with a custom snippet that simply displays the pagetitle along with the site_name
  2. The meta description needs to be different, and customizable for each page. Again, I'm doing this with a custom snippet I wrote called DynamicDescription. DynamicDescription will pull the first 25 words out of the document content, unless there is text in the MetaDescription template variable. The MetaDescription template variable is simply a text area template variable that is assigned to all page Templates. It allows the site manager to enter custom meta descriptions for each page on the site where they feel the automatic description is not suitable.
  3. The meta keywords need to be customizable. This is done with a template variable as well. The MetaKeywords template variable is an input box type and is assigned to all page Templates. I usually enter in a default string so all pages have keywords, and then customize them where necessary.
  4. ExtraHeadScripts is the final template variable in the Head Chunk. It is a simple text area template variable that allows the user to enter any extra information into the head for a particular page (stylesheets, javascripts, etc.). This is very useful on the homepage which usually has some custom js that no other pages have.

{{Banner}}
The Banner Chunk typically contains the logo and menu of the webpage but it really depends on how your HTML is laid out as to what it will contain. The goal of this Chunk is to have it contain any information that is directly below the body tag and above the content and that is consistent across the entire site.

<div id='wrapper'>
  <div id='banner'>
    <div class='logo'><a href='http://www.ehlydesign.com'><b>Ehly Design</b></a></div>
    <div id='menu-wrapper'>
      <div class='menu'>
        [\[Wayfinder?startId=`0`]]
      </div>
    </div>
  </div>
  <div id='content-wrapper'>
    <div id='content'>

As you can see, this Banner Chunk contains the markup right after the body tag of the HTML down to the content div tag. On this site it happens to include the logo and main menu, but like I said this is highly dependent on your layout. This markup is just what happens to be the same between the head and content. I can hear some of you asking, 'Why not just stick this information into the Head Chunk?' My reason for not doing that is simply because I've had situations where I've wanted to extract the banner portion of the site for placement in other layouts. For instance, you can render out the banner chunk to an html file, and include in a Wordpress theme, or a Gallery2 template, or any other third party app. Doing that will make your third party apps have the same menu as your MODx site.

{{Content}}
The content chunk is the piece of the Template puzzle that get's swapped for each new template. Here are two typical Content Chunks, one for the home page and one for all inside pages:

Homepage:

<div id='content-bar'></div>
<div id='content-footer'>
 <div class='container' style='margin-top:10px'>
 <div>
 <div style='padding-right:15px'>
 [*content*]
 <p style='text-align:center' class='trust-logos'>
 <a href='http://www.php.net' /><img src='assets/templates/2009/images/trust-logo-php.png' alt='PHP' /></a>
 <a href='http://www.mysql.com' /><img src='assets/templates/2009/images/trust-logo-mysql.png' alt='MySQL' /></a>
 <a href='http://www.modxcms.com' /><img src='assets/templates/2009/images/trust-logo-modx.png' alt='MODx' /></a>
 <a href='http://www.jquery.com' /><img src='assets/templates/2009/images/trust-logo-jquery.png' alt='jQuery' /></a>
 <a href='http://www.wordpress.org' /><img src='assets/templates/2009/images/trust-logo-wordpress.png' alt='WordPress' /></a>
 </p>
 </div>
 </div>
 <div class='span-17 last ss'>
 <div id="slideshow-container">
 <ul id="slideshow">
 {{Ditto_SlideshowCall}}
 </ul>
 </div>
 </div>
 </div>
</div>

Inside:

<div id='content-bar'></div>
<div id='content-footer'>
  <div id="breadcrumbs">[\[Breadcrumbs]]</div>
  <div class='container'>
  <div>
    <h1>[*pagetitle*]</h1>
  </div>
  <div>
    [*content*]
  </div>
  <div class='span-8 push-1 last'>[*sidecontent*]</div>
  </div>
</div>

From these two examples you can derive that the homepage contains more special features than the inside page. It has a slideshow, some logos, and content, while the inside page features the normal pagetitle, content, and sidebar.

{{Footer}}
The Footer Chunk contains anything after the content to right before the closing body tag. Again, the contents will depend on your html template , but this typically includes any content that is repeated on every page that is below the main content, the copyright statements, etc. I've also seen it contain the main logo of the site and the main menu (some sites do this for SEO). Here is what the example site footer looks like:

</div>
<div id='util'>
  <a href='/clients'>client login</a>
</div>
<div id='footer'>
  <div class='container'>
    <div class='span-10' id='devtrench-feed'>
      [!SimplePie!]
    </div>
    <div class='span-8'>
      &nbsp;
    </div>
    <div class='span-8 last'>
    </div>
  </div>
  <div id='logo-bottom'><img src='assets/templates/2009/images/ehlydesign-logo-sm.png' alt='Ehly Design' /></div>
 </div>
</div>
</div>

{{FooterCode}}
The FooterCode Chunk comes right after the footer and before the closing body tag so that you can place javascript right before the closing body tag. I separate out the Footer, FooterTag and closing tags for the same reason as I do for the Banner. If I want to extract the Footer Chunk for placement in a third party app, I don't want it to contain any closing tags or javascripts.

Conclusion

As you can see this templating strategy for MODx is very easy to put in place, but how does it scale better than just putting the whole template HTML into a Template? At their start, most sites usually require at least 2 templates (homepage and inside page), and some even more. Using this strategy, it's very easy to duplicate templates and only have to modify the Content Chunk. In the future, if a menu needs to be added to the site, you'll most likely only need to add it to the Banner or Footer chunks, and not into every single template. It's especially helpful when adding new javascripts to the FooterCode chunk. You also have the ability to render out the Banner and Footer chunks for third party apps. It also minimizes code decay - the differences that 'appear' in repetitious code over time.

I also want to point out that this is a strategy, not something set in stone (hardly anything in MODx is really set in stone). Obviously, your template may require you to adjust things here and there, but its the overall approach that's important. Hopefully this tutorial has taught you that.