Movable Type User Manual: DYNAMIC PUBLISHING

« Table of Contents


Movable Type's dynamic publishing allows you to combine static page generation with dynamic pages on a per-template basis. You can use this to balance the publishing and traffic for your weblog, and it gives you the best of both worlds: you can turn on static page generation for frequently-requested pages like your site index and feeds, and use dynamic pages for your monthly, individual, and other archive pages. This completely eliminates the need to manually rebuild your files; when you update the design of your archive templates, for example, the design of your site will immediately be updated without requiring you to rebuild.

Installation and Requirements


In addition to the requirements for Movable Type itself, the dynamic publishing option has the following requirements:

Enabling Dynamic Publishing

  1. Turn on the dynamic page option in Movable Type.
    Go to the ``Templates'' panel in Movable Type and choose either ``Build archives dynamically'' or ``Custom'' from the ``Dynamic Building Options'' menu. If you choose ``Custom'', you will need to edit each template you want to enable as dynamic and select the ``Build this template each time it is visited'' option.

  2. Set up the template cache directory.
    In your weblog's root directory, create a new subdirectory named templates_c. It should have a permission mask of 777.

  3. For Apache web servers: set up your .htaccess file.
    In your weblog root directory, you need to create a .htaccess file which will handle request for dynamic pages. This file should look like this:
    # Disable fancy indexes, so mtview.php gets a chance...
    Options -Indexes
      <IfModule mod_rewrite.c>
      # The mod_rewrite solution is the preferred way to invoke
      # dynamic pages, because of its flexibility.
       # Add mtview.php to the list of DirectoryIndex options, listing it last, 
      # so it is invoked only if the common choices aren't present...
      <IfModule mod_dir.c>
        DirectoryIndex index.php index.html index.htm default.htm default.html default.asp /mtview.php
       RewriteEngine on
       # don't serve mtview.php if the request is for a real directory
      # (allows the DirectoryIndex lookup to function)
      RewriteCond %{REQUEST_FILENAME} !-d
       # don't serve mtview.php if the request is for a real file
      # (allows the actual file to be served)
      RewriteCond %{REQUEST_FILENAME} !-f
      # anything else is handed to mtview.php for resolution
      RewriteRule ^(.*)$ /mtview.php [L,QSA]
     <IfModule !mod_rewrite.c>
      # if mod_rewrite is unavailable, we forward any missing page
      # or unresolved directory index requests to mtview
      # if mtview.php can resolve the request, it returns a 200
      # result code which prevents any 4xx error code from going
      # to the server's access logs. However, an error will be
      # reported in the error log file. If this is your only choice,
      # and you want to suppress these messages, adding a "LogLevel crit"
      # directive within your VirtualHost or root configuration for
      # Apache will turn them off.
      ErrorDocument 404 /mtview.php
      ErrorDocument 403 /mtview.php

    (If you already have a .htaccess file, simply append the above lines to it.)

    The ``mtview.php'' script referenced above will be created once you do a rebuild of the new ``Dynamic Site Bootstrapper'' index template. If your weblog root is in a subdirectory of your site, adjust the path to the ``mtview.php'' script above to match the actual location of this file (ie: use ``/weblog/mtview.php'' if your weblog root is under a ``weblog'' directory).

  4. For Microsoft IIS web servers, customize your error handlers:
    For Internet Information Server, you will need to configure your weblog directory to use the ``mtview.php'' script as a custom error document. You should use it for 403 and 404 errors.

Advantages of Dynamic Publishing

Combining Static and Dynamic Publishing

Movable Type has added dynamic publishing as an option in addition to the static publishing it is known for. You don't have to choose just one or the other-- you can have any combination of the two.

This means you can enable dynamic publishing for certain index and/or archive templates and use static publishing for others. This gives you a lot of flexibility in how you publish your site. Depending on your traffic flow, you may want to continue to publish your index and Atom/RSS/RDF feeds statically if those pages receive heavy traffic.

Archive pages are generally the best choice for dynamic publishing since they receive less traffic and consume the most disk space.

Optimizing your Dynamic Pages

Keep in mind that by using dynamic publishing, each un-cached page view will result in a number of database queries to build the page. Depending on the performance of your web server and the complexity of your templates, this may take anywhere from a fraction of a second to several seconds. Here are some tips you can use to optimize the speed of your dynamic pages:

Page-level Caching

Note: This is an experimental features which may not work in some environments.

Another way to optimize the dynamic publishing feature is to enable page-level caching. This feature gives you near-static page speed, since the dynamic pages are cached into the file system from one request to the next. Over time, this will cause your disk space savings to shrink, but the performance benefit may be worth it.

To enable page-level caching, you will need to create a ``cache'' subdirectory in your weblog's root directory. It should also have a permission mask of 777. After doing this, edit your ``Dynamic Site Bootstrapper'' index template and add this line:

$mt->caching = true;

It should be placed just above the line that reads ``$mt->view();''. Removing this line will disable the caching option.

Once you do that, your dynamic pages will cache themselves into the cache directory you created. Cached pages are individually rebuilt (and only upon request) when the weblog content is newer than the cached page.

Conditional Requests

If you would like, you can enable conditional requests (HTTP 304 responses) for your dynamic pages. Usually when pages are generated dynamically, they are generated unconditionally. In some cases, this is desired, so conditional requests are disabled by default. You can enable them by adding this to your ``mtview.php'' script:

$mt->conditional = true;

Add this above the ``$mt->view();'' line. The timestamp that is associated with the conditional requests is the last time your weblog was modified (any portion of your weblog, including comments, trackback pings, template changes, etc.).

You can even get fancy and set the conditional behavior conditionally! Here's how you can enable it just for your feeds:

if (preg_match('/(index|atom)\.(rss|xml|rdf)/',
               $_SERVER['REQUEST_URI'])) {
    $mt->conditional = true;

PHP Plugin API

Movable Type's dynamic publishing mode supports plugins as well. The architecture is different, but should be familiar in some respects.

Two key components to the PHP-based dynamic publishing engine are the Smarty template package ( and Justin Vincent's ezSQL library (

The ``php'' subdirectory under Movable Type's main directory contains all the files and resources related to the dynamic publishing engine:

       lib/      Native MT tags and modules
       extlib/   Third-party packages (ezSQL and Smarty)
       plugins/  Third-party MT/PHP plugins

Plugin files should be placed in the ``plugins'' directory. To develop MT/PHP plugins, you should familiarize yourself with how to create add-ons for Smarty. Custom blocks, functions and modifiers are the basis for adding container tags, variable tags and global filters respectively for MT/PHP.

There is a wealth of information on how to write Smarty routines on the Smarty web site: