|MySQL Conference and Expo April 14-17, 2008, Santa Clara, CA|
Developing Movable Type Plug-insby Timothy Appnel
One of the most significant things to come out of the weblog movement is the availability of low-cost and relatively easy-to-use tools for publishing. One of the most sophisticated and powerful is Movable Type, developed by Ben and Mena Trott of Six Apart. Movable Type's features are so rich that the tool's uses have begun to transcend weblogging.
Written in a highly modular Perl object-oriented (OO) style, Movable Type (MT) has an open code base (it's not open source—an important distinction) that makes the browser-based tool quite flexible and easily modifiable to adapt to any number of publishing applications. In recent releases, extending MT has become easier and more elegant with the introduction of a plugin framework that continues to be enhanced with each new release.
In this article I will cover the MT plugin framework, its complete API, and the basics of hooking into the core systems operation and its data persistence service. It's assumed that you're somewhat knowledgeable with Perl and familiar with its OO style. (See Simon Cozens' article on Object-Oriented Perl for a quick primer.) With the richness of Perl and the MT system, a whole book could be written on the subject. We'll just cover the basics in this whirlwind tour.
The Movable Type Plugin Framework
As I've mentioned, Movable Type provides developers with a framework to easily and elegantly extend the base functionality of the system using OO Perl. Generally speaking, plugins are limited to MT's template processing engine, to add variable, container, and conditional tags in addition to global filters. In version 2.6, the plugin framework began to branch out from template processing by introducing an API for hooking in text-formatting engines and access to MT's data persistence mechanisms. We'll go into the specifics of what these can do for you throughout the article.
Installing plugins are quite easy. Simply place the code in a subdirectory named
In addition to the plugin framework, MT provides an extensive and well-documented array of functionality through its OO Perl modules, giving developers the ability to create command-line utilities to their own extension applications. We won't be able to cover this topic in this article, but the documentation is available here.
Let's dive into our first plugin.
MTHelloWorld: Your First Movable Type Plugin
Let's start with a basic variable tag that simply inserts a value into a template when in encountered.
Save this code to a file named
In the first line I declared a package of
In the second line we call into service
Finally we register our HelloWorld tag by passing in a single key-value hash. The key is the tag name (case matters) you are registering. The MT prefix is assumed and will be appended by the system during processing. The value is a subroutine that will be called when the tag registered is incurred during processing. Here I placed the subroutine directly in the hash because it was so simple, but it's generally good form to use the anonymous subroutine to call an external named subroutine. This practice makes your code easier to read and affords you the advanced practice of reusing the subroutine with multiple tags.
Let's add a bit more sophistication to this plugin. Suppose we want to be able to say "Hello" to a specific world, and define that world in our template markup. Here is what our code may look like:
Now we can use
Since our tag's routine is getting a bit more sophisticated, in the third line we've moved it to a named subroutine that's external to this command. Moving to that subroutine, we see in the first two lines that MT passes template tag plugins two references for use in our plugin routine. I've coded them longhand for clarity, but you can use whatever brand of Perl kung fu you practice to work with these references.
The first reference declared as
The second reference declared as
NOTE: Our particular example would always insert something into a template. However, in some instances you may decide to insert nothing, based on some condition. In these cases you must return a null string and not an undefined value. An undefined value returned from a plugin is treated as an error and will stop all processing.
Variable replacement isn't really that interesting. The real power of plugins is when they hook into the system and are used in combination with other tags. Before continuing on to the rest of the plugin framework, we'll review some of the common ways we can hook into MT's processing.