Templating in MT
his provides a summary of some of the new features and tags available in Movable Type’s new templating engine.
Movable Type publishes content using text-based templates. A typical MT template has content that looks like this:
<MTEntries lastn=”5”>
<h1><$MTEntryTitle$></h1>
<div class=”entry-body”>
<$MTEntryBody removehtml=”1”$>
</div>
</MTEntries>
This
template is producing HTML (or XHTML) content, as it is intermingled
with HTML-based tags. When MT processes a template it only looks at
things that look like <MT…> or <$MT…$>. Everything else
is output verbatim, which means that MT templates can produce many
different kinds of documents, HTML being one of them.
In MT the above <MTEntries…> tag is known as a ‘block’ tag, one that
wraps around other content. The above <$MTEntryBody$> tag is
known as a ‘function’ tag, one that outputs a value of some kind (the
‘$’ characters are optional here, but they can help to identify this
kind of tag when looking at your template). In previous releases, block
tags were called ‘container’ tags, function tags were just called tags.
The ‘remove_html’ attribute used in the <$MTEntryBody$> tag is
one of MT’s ‘modifiers’— a special keyword that causes the value of
the tag to be processed on some way (in this case, to strip it of any
HTML content).
There. That’s the fundamental concept to writing
MT templates. Now you just need to know what tags are available to use
and what they do. There’s a reference for that, but this document is
going to proceed with describing some of the new MT features.
MT emplating Enhancements
MT tags are now case-insensitive
MT
templates are no longer case-sensitive. By this, I mean that you can
write a tag like <MTEntries> as <mtentries> or
<MtEntries>. This makes MT much more forgiving when it comes to
composing templates. You no longer have to remember if you should write
<MTSubCategories> or <MTSubcategories> for instance.
MT tags will allow a ‘namespace’ delimiter
This
is a small point, but some will appreciate that you can now write MT
templates with a XML-like namespace delimiter, such as
<MT:Entries> (or <mt:entries>). For some, this is more
aesthetically pleasing.
MT tag attributes can interpolate variables
The best way to describe this is to demonstrate:
<MTSetVar name=”lastn” value=”5”>
<MTEntries lastn=”$lastn”>
…
</MTEntries>
Here,
the value of the ‘lastn’ attribute of the ‘Entries’ block tag is being
supplied by a template variable (coincidentally named ‘lastn’). We
currently do NOT support complex expressions like this:
<MTEntries categories=”$cat1 OR $cat2”>
‘Array’ of values for attributes
A
syntax we borrowed from the Smarty templating language (which we use as
the behind-the-scenes engine for our dynamic publishing) is the ability
to assign multiple values to an attribute. For instance:
<MTVar name=”myvar” regexreplace=”/[^a-z]+/g”,”“>
Here,
a comma is used to delimit (a colon may also be used, which is what
Smarty supports) multiple values for the ‘regexreplace’ modifier.
Here, the first value is used as the pattern and the second value is
used as the replacement. This expression actually works in MT, since
we’ve added a ‘regexreplace’ modifier to the core (something the
dynamic publishing side has always supported, since it was supplied
through Smarty).
MT core Tag Enhancements
Movable
Type now uses it’s own template language for processing it’s
application templates. This means a departure from using the
HTML::Template Perl module, and it means that MT templates must provide
more flexible conditional and ‘looping’ processing. So we have extended
the template language and some of the core tags to allow for more
control.
<MTIf>
Movable Type introduces a new conditional ‘If’ tag that lets you test and compare template variables. Some sample uses:
<mt:if name=”myvar”>
‘myvar’ is set to something
</mt:if>
It also supports the ‘Else’ clause:
<mt:if name=”myvar”>
‘myvar’ is set to something
<mt:else>
‘myvar’ is not set
</mt:if>
(Note
that with MT, the ‘Else’ tag may optionally be closed. If it is left
unclosed, MT will assume it is closed with the next closing block tag.)
The If tag supports a number of operations…
<mt:if name=”myvar” eq=”some value”>
This
does an ‘equal’ test, comparing the value of ‘myvar’ with the content
of the ‘eq’ attribute. Other operational attributes include: ‘ne’ (not
equal), ‘gt’ (greater than), ‘lt’ (less than), ‘ge’ (greater than or
equal), ‘le’ (less than or equal), and ‘like’ (which supports a regular
expression test).
The ‘like’ operator tests for a regular expression match like this:
<mt:if name=”myvar” like=”^[A-Za-z]+$”>
<MTUnless>
An Unless tag is provided as a counterpart to the If tag. It inverses the logic of the test.
<MTLoop>
If
a MT variable contains an array of content, a MT Loop block tag may be
used to process that array of data. As it does, the value of each
element of the array is taken and put in context as the insides of the
Loop tag are processed. If the array element is a Perl hash, it will
place the content of that hash into the variable space of the template
so that the <MTVar> tag can output them. If the array element is
some simple value, that value is placed into the pseudo-variable
‘value’ which may also be accessed by the <MTVar> tag. This
is the counterpart to the HTML::Template ‘TMPLLOOP’ tag and is
primarily used in MT application templates.
<MTLoop name=”mylist”>
<MTVar name=”name”> - <MTVar name=”value”>
</MTLoop>
Such a loop would expect a template variable ‘mylist’ that has this content:
[ { name => ‘foo’, value => ‘bar’ },
{ name => ‘flip’, value => ‘flop’ } ]
Loops
also populate other ‘HTML::Template’ pseudo-variables, such as
‘counter’ (the array element number being processed, starting with
‘1’), ‘odd’ (set when the loop element is odd), ‘even’ (set
when the loop element is even), ‘first’ (set for the first item in
the loop), ‘last’ (set for the last item in the loop).
<MTVar>, <MTGetVar>, <MTSetVar>, <MTSetVarBlock>, <MTSetVarTemplate>
Template
variables can be set/retrieved with this family of tags. ‘GetVar’ is an
alias for ‘Var’ (which is just shorter to write, but you’d expect
‘GetVar’ to be available, since we use ‘SetVar’ for setting variables).
‘SetVar’ is a function-style tag, for setting simple values.
‘SetVarBlock’ is a block tag, for setting complex values.
‘SetVarTemplate’ is for assigning a MT template to a variable. More on
this in a minute.
So for simple variable assignment:
<MTSetVar name=”myvar” value=”value”>
And to output a variable:
<MTVar name=”myvar”>
If
you want to assign something that uses MT tags, you’ll have to use
‘SetVarBlock’ to wrap the MT tags (since you can’t place MT tags inside
attributes of another MT tag):
<MTSetVarBlock name=”myvar”>
<MTEntryTitle>
</MTSetVarBlock>
This
assigns the evaluated result of what is inside the block to the
‘myvar’ variable. So in this case, the title of the MT entry in
context is assigned to the ‘myvar’ variable.
Which brings us to
‘SetVarTemplate’. There will be cases where you may want to assign a MT
template expression to a variable. For instance:
<MTSetVarTemplate name=”entrymetadata”>
<MTEntryDate> - <MTEntryID>
</MTSetVarTemplate>
This
winds up assigning a mini-template to the ‘entrymetadata’ variable.
The content itself is not evaluated immediately… and because of that,
it isn’t necessary for a entry context to be available at the time the
variable is assigned.
Now, once you actually write:
<MTVar name=”entrymetadata”>
The
mini-template in ‘entrymetadata’ is processed and evaluated, producing
the content of that template, in the context the ‘Var’ tag is used in.
<MTInclude>
The MT include tag has been around for a while, but there are a few very important changes to it that should be mentioned.
- Includes now are always processed for MT tags. In prior releases, if you did an include that drew content from a file (using the ‘file’) attribute, it would be output verbatim, but now the default behavior is to evaluate the content as a MT template. We may add another attribute to prevent MT tag processing, but no option exists for that at this point.
- A new ‘name’ attribute is supported which lets MT templates draw from the MT application template directory. This attribute is for use by MT application templates.
- MT Include tags will ‘pass-through’ any unrecognized attribute/value pairs as template variables to the included template. This makes it possible to say…
Summary
All of these changes make MT templates much more flexible and powerful, without complicating the basic syntax that many have found to be so approachable and easy to learn.
Dave Baker on October 8, 2007, 12:08 p.m. Reply
Great stuff! But a nit to pick:
Movable Type 4 now uses it’s own template language for processing it’s application templates.
should be =>
Movable Type 4 now uses its own template language for processing its application templates.
jackvinson.myopenid.com on November 5, 2007, 12:58 p.m. Reply
Where is the list of variables that MT4 uses by default? And the list of options for those variables. For example: the name and options for the page layout variable.
Richard on November 6, 2009, 8:27 a.m. Reply
I learned today in the forum:
Where does it say this in the documentation?
stephenb on December 12, 2012, 10:57 a.m. Reply
@victor100: Could you elaborate on that? I actually think the template language is one of MTs stronger points.