A Tag within a Tag

04/18/2005

In Movable Type, we use tags for defining the flow within a template and for accessing the database. You can influence a tag's behavior with the help of attributes. These attributes define a value for some parameter.

Unfortunately, the value for an attribute may only be a constant. However, you will sometimes have the need for setting the value to the result of another tag. Movable Type will not support such a situation, but a plugin will help.

An Example

Suppose you have a template module that you want to include from many different places. For example, you want to call this module from both an individual entry archive and the main index. Inside the template, you then want to check for certain entry IDs. Something like...

  • If I am on page "Contact", then do the following...
  • If I am on page "Sitemap", then do the following...

You might be tempted to code this comparison with the Compare Plugin (for an introduction please have a look at Comparison needed for conditional Generation).

<MTIfEqual a="[MTEntryID]" b="123">
...
</MTIfEqual>

Of course, you have to replace "123" with the specific entry ID that you want to check. This comparison will perfectly work, if an individual entry archive is rebuilt. However, if the rebuild process is in the context of the the main index page, no entry ID is defined, and rebuilding the site will fail with an error message.

This seems to be no problem: simply define a variable of your own. Take care that the variable is also known in the context of the main index template, and then check against this variable.

<MTIfNonEmpty tag="MTEntryID">
<MTSetVar name="mgs_id" value="<MTEntryID>">
<MTElse>
<MTSetVar name="mgs_id" value="">
</MTElse>
</MTIfNonEmpty>

However, this scenario will not work. It shows one of Movable Type's limitations: it does not evaluate the right side of the assignment correctly. The right side has to be a constant. Another tag is forbidden in this situation.

Now it is time, to have a plugin take over the work.

The MTTagInvoke Plugin

The so-called MTTagInvoke Plugin is able to handle the above situation.

Installing the plugin is very simple. After having downloaded the plugin from the above location, you have to copy the file »mttaginvoke.pl« into the »plugins« directory below your Movable Type installation.

This simple copying is enough for making the function inside the file known to Movable Type.

You can use MTTagInvoke in a couple of ways. Here, I will concentrate on solving the above problem. The code for assigning the entry ID to a variable of my own is as follows.

<MTTagInvoke tag_name="MTSetVar">
<MTTagAttribute name="name">mgs_id</MTTagAttribute>
<MTTagAttribute name="value"><MTEntryID></MTTagAttribute>
</MTTagInvoke>

At first sight, this code looks a little bit complicated. So let me explain.

  • Initially we are executing the MTTagInvoke tag.
  • The MTTagInvoke is given a couple of parameters.
  • The most important parameter is given with the »tag_name« attribute. Here we specify the tag that must be invoked by MTTagInvoke. In our case it is the »MTSetVar« tag.
  • Of course, the parameters for the »MTSetVar« tag must be specified, too. These are the name and the value for the variable, which is to be set. Both of these are defined with the help of the new »MTTagAttribute« tag. The important point is the fact that the right side of the assignment is specified as the contents of the »MTTagAttribute« tag. Here, other tags are allowed.

The »MTTagInvoke« tag allows other ways of handing over the attributes for the indirectly called tag. The above would also have been possible with the following.

<MTTagInvoke tag_name="MTSetVar" name="mgs_id">
<MTTagAttribute name="value"><MTEntryID></MTTagAttribute>
</MTTagInvoke>

I prefer the first way of coding. At least for me, the structure is cleaner.

Solving the Task

After having understood the »MTTagInvoke Plugin«, the solution for our problem is simple.

<MTIfNonEmpty tag="MTEntryID">
<MTTagInvoke tag_name="MTSetVar">
<MTTagAttribute name="name">mgs_id</MTTagAttribute>
<MTTagAttribute name="value"><MTEntryID></MTTagAttribute>
</MTTagInvoke>
<MTElse>
<MTSetVar name="mgs_id" value="">
</MTElse>
</MTIfNonEmpty>

...

<MTIfEqual a="[MTGetVar name='mgs_id']" b="123">
...
</MTIfEqual>

The first couple of lines make sure that the variable »mgs_id« exists. If we are in the context of an entry, its entry ID will be assigned to my variable. If we are in another context (for example the main index page), the variable will be assigned an empty string.

The code fragment at the bottom checks, whether the entry ID is equal to a specific ID. If it is equal, some HTML will be generated. If it is not equal, the section will be skipped.

So by having copied the entry ID into my own variable (or initializing it with an empty string), the comparisons within the template are much easier. I do no longer have to handle the situation, where the entry ID is not defined. I can rely on my variable being well defined, all the time.

mgs | 04/18/2005

Feedback is welcome!

What do you think about this entry? Was it interesting or boring? I would like to hear your comments. If the text was helpful, please consider setting a link to http://www.movable-type-weblog.com/.

No spam please!

For protecting this weblog I have installed the MT-Approval Plugin. You have to view a new comment in preview mode, before it is saved on the server. Moreover, I will view your comment manually, before it is published. You can find more information on the subject in the entry Weblog Spamming Basics.

With an active TypeKey session, your comment will be published immediately.

Post a new comment

TypeKey has temporarily been disabled at this location. Please create your comment without using TypeKey or log in from the preview dialog.




Remember Me?


Comment

webdetail [TypeKey Profile Page] | July 5, 2005 06:04 AM

I am trying to make a menu list of entries within a category to be placed on the sidebar on the individual archive template, based on the category of the individual entry. Unfortunately, because the category parameter of the MTEntries tag will not take the tag MTEntryCategory tag, this list cannot be built automatically. Currently I am using the compare plugin, but the problem is that I have to do a literal compare for every category that exists.

example
MTIfEqual a="[MTEntryCategory]" b="About"
MTEntries category="about"
etc.

If I create a new category, I have to edit the template to sort for that category.

How can I use the MTTagInvoke to create these menu lists automatically?

Comment

Shannon Moeller | April 26, 2006 04:55 PM

Awesome. This fixes a problem I've been working on for a couple days. Didn't know about the MTTagInvoke plugin. Props.