Changes to MTIfNonEmpty / MTIfNonZero tags in MT 3.16

| 2 TrackBacks

While reviewing my referers, I ran across an entry on Tiny Pineapple that discussed how my Replacement for MTCommentFields no longer worked in MT 3.16:

But after a recent upgrade to Movable Type 3.16, it stopped working. And after poking around a bit, I figured out why.

In addition to <MTCommentFields>, Movable Type 3 also introduced a new, but undocumented, template tag called <MTIfNonZero>. The only reference to it you'll find in the Movable Type documentation is in one of the Category Template Tag examples:

<MTIfNonZero tag="MTCategoryCount">
<li><a href="<$MTCategoryArchiveLink$>" title="<$MTCategoryDescription$>">
<MTCategoryLabel></a>
<MTElse>
<li><MTCategoryLabel>
</MTElse>
</MTIfNonZero>

From the example we can deduce that you can use <MTIfNonZero> to determine whether or not the value of a certain template tag is zero. But TweezerMan went one step further and used it to determine whether or not the value of a variable was equal to zero. And to do so, he used two different syntaxes:

<MTIfNonZero tag="GetVar" name="preview"><$MTCommentPreviewAuthor$>
</MTIfNonZero>

...and...

<MTIfNonZero tag="MTGetVar" name="preview"><$MTCommentPreviewAuthor$>
</MTIfNonZero>

But while those may have worked in Movable Type 3.15, neither seems to work in Movable Type 3.16.

This got me to wondering: Did Six Apart really change the behavior of MTIfNonZero tags in MT 3.16?

MTIfNonZero is an undocumented MT3 tag. It works just like like the MTIfNonEmpty tag, except that it checks to see whether a given tag has the value of "0", instead of whether it is empty. When specifying the tag name in the 'tag' attribute, the initial 'MT' of the tag name is optional - it will work either way.

Both MTIfNonZero and MTIfNonEmpty had an undocumented feature: Any additional attributes provided with the MTIfNonZero or MTIfNonEmpty tags were passed along with the tag name to be evaluated. Take this code, for example:

<$MTSetVar name="myvar" value="1"$>
<MTIfNonZero tag="MTGetVar" name="myvar">
... some template code here ...
</MTIfNonZero>

The MTIfNonZero tag would pass the 'name' attribute along with the tag to be checked (in this case, MTGetVar), causing it to evaluate <$MTGetVar name="myvar"$> and checking the value of that particular MT variable.

I compared the code in MT 3.14 and MT 3.16 for the MTIfNonZero and MTIfNonEmpty tags in lib/MT/Template/Context.pm. The code for both of these tags has been changed in MT 3.16 to specifically not pass additional attributes.

In the above example, the MTIfNonZero tag in MT 3.16 will only see and evaluate <$MTGetVar$>. Without the 'name' attribute, <$MTGetVar$> is meaningless, and the code no longer works.

I asked Six Apart why this behavior was changed, and received this answer:

We removed the $args from the parameter list to the sub-handler because it was causing the $args of the parent tag to be affected in cases where sanitize (and potentially other tag handlers) is used.

So, it would have consequences when used like this:

<MTIfNonEmpty tag="MTCommentBody">
<img src="..." alt="Comment Icon" /> <MTCommentBody>
</MTIfNonEmpty>

Because sanitize gets added to the <MTCommentBody> tag's args, passing through the arguments from the MTIfNonEmpty tag caused the sanitize argument to be added to MTIfNonEmpty, which would then strip the inner <img> tag.

So, we'll be looking into a way to get around that better in future versions, i.e., in a manner which will attempt to also restore the functionality you were taking advantage of.

Basically, any global attributes that appeared in an MTIfNonEmpty or MTIfNonZero tag would get applied both to the tag being evaluated, and to the contents of the MTIfNonEmpty / MTIfNonZero container tag. An additional complicating factor is that some MT tags silently add a sanitize="1" attribute by default (MTCommentAuthor, MTCommentEmail, MTCommentURL, MTCommentBody, MTPingTitle, MTPingURL, MTPingBlogName, MTPingExcerpt).

Since there is currently no way to tell an MTIfNonEmpty or MTIfNonZero tag whether a particular (global) attribute should be applied to the tag being evaluated, the contents of the container tag, or both, the passing of additional attributes to MTIfNonEmpty and MTIfNonZero tags was disabled in MT 3.16.

Most MT tags that can be tested with MTIfNonEmpty or MTIfNonZero do not require additional attributes to be evaluated, so this change in behavior would not cause any issues. MTGetVar happens to be one exception - this tag now cannot be tested in an MTIfNonEmpty or MTIfNonZero tag. In that case, you'd need to use something like the Compare plugin to do so.

2 TrackBacks

Changes to MTIfNonEmpty / MTIfNonZero tags in MT 3.16... Read More

In der Movable Type Version 3.16 gab es offensichtlich Tag-´┐Żnderungen. Die MTIfNonEmpty / MTIfNonZero Tags und deren aktuelle Anwendung beschreibt der Beitrag im Movabletype-Blog The Tweezer's Edge. Read More