Proposal:TemplateTagWhitespace

From MovableType

Contents

Abstract

MT templates have a natural structure about them and it is natural to want to use proper indentation to show the structure and to make them easier to read. However, when you do this, the published output often times has a lot of additional whitespace added to it as a result. This proposal outlines a way to remove this unwanted whitespace.

Problem Statements

  • MT templates are difficult to read when tags are all placed together; it is easier to read them when whitespace is utilized. At the same time, this "formatting" whitespace should not be published.
  • It is possible to eliminate unwanted whitespace inside a MT container tag by using the global "trim" tag modifier, but adding 'trim="1"' to each tag that should have it makes the template really cluttered. Worse, it could remove whitespace from the content of an inner tag, which you may wish to preserve.

Background

Movable Type's templates provide the user with the utmost control in what is published. Every character outside of MT tags is preserved and output as it is written, whitespace included (this has not traditionally been the case with dynamic publishing, but the latest release of MT's dynamic engine preserves whitespace also). This is not always desirable. Consider the following MT template:

   <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   <mt:Ignore></mt:Ignore>
   <mt:Var name="title" value="This is a test">
   <mt:Var name="subtitle" value="And so is this">
   <html>

In this case, the MT tags appearing above the opening 'html' tag would be processed and replaced with an empty string. The newline character after each of them would be left untouched. So the output would look like this:

   <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   
   
   
   <html>

Again, this is typically undesirable and for some, unexpected. A user would probably prefer this:

   <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   <html>

But, how do you go about knowing what whitespace is important and what is not? If we were publishing a CSV file, instead of a HTML file, we may be more concerned about whitespace. For example:

   <mt:Entries>
       "<mt:EntryTitle>","<mt:EntryDate>"
   </mt:Entries>

Would produce this:

   --start of file
   
       "Title of Second Entry","November  2, 2008  9:45 PM"
       
       "Title of First Entry","November  2, 2008  9:26 PM"
       
   --end of file

When you really want this:

   --start of file
   "Title of Second Entry","November  2, 2008  9:45 PM"
   "Title of First Entry","November  2, 2008  9:26 PM"
   --end of file

Requirements

The requirements for a solution are:

  • The syntax change should be unobtrusive
  • The syntax would be optional (naturally; the user will want to preserve whitespace in cases)
  • By default, all whitespace should be preserved, as it is today

Effect on the platform/existing features/code

There are key places in the MT codebase where we test for the existence of a MT tag in a string. This relies on a regex match, and these places may require alteration if the syntax changes that pattern. Preferably, such a test should be moved into MT::Template itself and should be called when needed.

Effect on existing, upgrading users

There is a chance that plugins that rigidly match against the MT template syntax may be affected. Existing user templates would not be updated to use the feature, so they should be unaffected.

Effect on future new users

Going forward, MT's default templates would employ this feature to reduce extraneous whitespace.

Project Plan

The goal would be to release this change in the next feature release of Movable Type.

Implementation Notes

The recommendation to implement this feature is to use a '-' character at the end of a MT tag to signify that following whitespace should be eliminated. An example looks like this:

   <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   <mt:Ignore></mt:Ignore ->
   <mt:Var name="title" value="This is a test" ->
   <mt:Var name="subtitle" value="And so is this" ->
   <html>

The above template would produce the following output:

   <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   <html>

In the case of a function tag that also uses the optional "$" character to delimit the tag, those would look like this, when employing this feature:

   <$mt:Title$->

Note that the "$" characters are entirely optional, and the last "$" especially so. You could also write the above like this (which is preferred, see "Compatibility Notes" below):

   <$mt:Title ->

The "-" character was selected since it is easy to remember that it will "subtract" whitespace; the placement at the end of the MT tag was chosen since it forms an arrow, which provides a convenient mnemonic: subtract whitespace at right. Note that the implementation would not require a space preceding the "-" character to work, but it is recommended since it preserves backward compatibility (see "Compatibility Notes" below) and makes it stand out better when reading the template.

There are many alternatives to this recommendation, but none meet the stated requirements as well (a custom attribute, a special MT tag, etc.).

  • The MT test suite should be updated if necessary to fix any tests that break as a result of implementing this feature. New tests should be added to cover the feature.
  • MT documentation should be updated to reflect the new syntax.
  • MT's CodePress syntax JavaScript profile should be updated to reflect the new syntax.
  • We are only implementing support to remove whitespace that FOLLOWS a MT tag and not providing a syntax for removing whitespace that precedes a MT tag. This is by design. Syntax for doing that looks like this:
    • Block tags: <-MTEntries> ... <-/MTEntries>
    • Function tags: <-$MTEntryTitle>

Which is more of a visual break from existing MT templating, affords no backward compatibility and has less practical utility overall. In my estimation, the positives from implementing support do not outweigh the negative impacts.

Compatibility Notes

If you want to write templates in such a way to use this feature for MT instances that support it, but also be backward-compatible, so that the templates also work in older Movable Type releases that may not support the feature, you can do it this way.

  • Block tags:
    <MTEntries -> ... </MTEntries ->
  • Function tags:
    <$MTEntryTitle ->
  • Variables:
    <$MTGetVar name="foo" ->

Writing in this way, you can support older versions of MT as well. Note that the space prior to the "-" character for block and function tags. This space is necessary for older MT releases; without it, MT would see an "Entries-" tag instead of "Entries", and "EntryTitle-" instead of "EntryTitle". A space is not required following a quote character as in the last example, but to be consistent with the other uses, it would be recommended.

Resources

Template Toolkit has a similar feature, one where you can provide 'hints' to remove whitespace that is before and/or after a given Template Toolkit tag.

Project Team

Below is a list of community members participating in the project. All users are linked to their wiki user page and project leaders are marked with an asterisk.

If you are interested in participating but still not sure, add yourself to the bottom of the list. You can italicize your name if you are interested but undecided.

Related Bugs

Please provide a link to any related bug in FogBugz.