1.1. Tag Syntax

ITL tags are similar to HTML in syntax, in that they accept parameters or attributes and that there are both standalone and container tags.

We will call an attribute a parameter if it may be called positionally or if it must be included (see the parameter and attribute sections below).

A standalone tag has no ending element, e.g.:

    [value name]

This tag will insert the user's name, providing they have given it to you in a form. A container tag has both a beginning and an ending element, as in:

    [if value name]
    You have a name. It is [value name].
    [/if]

We will usually call the ITL tags Interchange tags or just tags.

1.1.1. Standard Syntax

The most common syntax is to enclose the tag with its parameters and attributes in [square brackets]. If the tag has an end tag, the tag and its end tag will delimit contained body text:

  [tagname parameters attributes]Contained Body Text[/tagname]


Caveat -- macros: Some macros look like tags or end tags. For example, [/page] is a macro for </A>. This allows you to conveniently write [page href]Target[/page], but 'Target' is not treated as contained body text.


When using the [tagname ...] syntax, there must be no whitespace between the left bracket ('[') and the tagname.

If a tag name includes an underscore or dash, as in item_list, a dash is just as appropriate (i.e. item-list). The two forms are interchangeable, except that an ending tag must match the tag (i.e., don't use [item-list] list [/item_list]).

1.1.1.1. HTML-Comment

ITL also allows you to use '<!--[' and ']-->' as interchangeable alternatives to plain square brackets: [tagname] and <!--[tagname]--> are equivalent.

This allows you make your raw tags appear as comments to HTML browsers or editors. You might want to do this if your editor has trouble with ITL tags when editing Interchange page templates, or alternatively, if you want to use one .html file both as an Interchange template and as a static page delivered directly by your web server, without Interchange processing.

To properly HTML-comment contained body text, place your comment-style brackets appropriately, for example:

 <!--[tagname] Contained Body Text [/tagname]-->

Note that you must include whitespace between the HTML comment delimiters and the square brackets if you wish to actually comment out tag output in the browser. For example, if [value name] expands to 'Bill':

 '<!--[value name]-->'  becomes  'Bill'
 '<!-- [value name] -->'  becomes  '<!-- Bill -->'
1.1.1.1.1. Technical notes

While '<!--[' and '[' are completely interchangeable, the Interchange parser does not replace ']-->' with ']' unless it also sees '<!--[' at least once somewhere on the page. (This is a small parsing speed optimization.)

See the Template Parsing Order appendix if you are modifying the special administrative interface pages and intend to use this syntax.

1.1.2. HTML-Embedded

As an alternative syntax, you can usually embed an Interchange tag as an attribute within an HTML tag. This allows some HTML editors to work more easily with Interchange templates (though you should consider the above HTML-comment-style brackets first). The following is a basic example of HTML-Embedded syntax:

  <HTMLtag MV="tagname positional parameters" other HTML attributes>

The following examples will each loop over any items in the shopping cart, displaying their part number, description, and price, but only IF there are items in the cart.

    <TABLE MV="if items">
    <TR MV="item-list">
    <TD> [item-code] </TD>
    <TD> [item-description] </TD>
    <TD> [item-price] </TD>
    </TR></TABLE>
    [if items]
    <TABLE>
    [item-list]
    <TR>
    <TD> [item-code] </TD>
    <TD> [item-description] </TD>
    <TD> [item-price] </TD>
    </TR>
    [/item-list]</TABLE>
    [/if]


Note -- Disabling HTML-embedded tags for performance:

Avoid the HTML-embedded usage if you can.

The Foundation catalog included with Interchange disables parsing of the HTML-embedded syntax. This is for better performance, since it saves the server from checking every HTML tag for Interchange tag calls. This is done in the catalog by setting the pragma no_html_parse in catalog.cfg.


1.1.3. Named vs. Positional Parameters

There are two styles of supplying parameters to a tag: named and positional.

In the named style you supply a parameter name=value pair just as most HTML tags use:

    [value name="foo"]

The positional-style tag that accomplishes the same thing looks like this:

    [value foo]

The parameter name is the first positional parameter for the [value] tag. Some people find positional usage simpler for common tags, and Interchange interprets them somewhat faster. If you wish to avoid ambiguity you can always use named calling.

In most cases, tag parameters specified in the positional fashion work the same as named parameters. However, there are a few situations where you need to use named parameters:

  1. If you want to specify a parameter that comes positionally after a parameter that you want to omit, e.g. omit the first parameter but specify the second. The parser would have no way of knowing which is which, so you just specify the second by name. This is rare, though, because the first positional parameters are usually required for a given tag anyway.
  2. When there is some ambiguity as to which parameter is which, usually due to whitespace.
  3. When you need to use the output of a tag as the parameter or attribute for another tag.

1.1.3.1. Interpolating parameters

If you wish to use the value of a tag within a parameter of another tag, you cannot use a positional call. You must also double-quote the argument containing the tag you wish to have expanded. For example, this will not work:

    [page scan se=[scratch somevar]]

To get the output of the [scratch somevar] interpreted, you must place it within a named and quoted attribute:

    [page href=scan arg="se=[scratch somevar]"]

Note that the argument to href ('scan') did not need to be quoted; only the argument to arg, which contained a tag, needed the quotes.

1.1.4. Universal Attributes

Universal attributes apply to all tags, though each tag specifies its own default for the attribute. The code implementing universal attributes is external to the core routines that implement specific tags.

1.1.4.1. interpolate

This attribute behaves differently depending on whether the tag is a container or standalone tag. A container tag is one which has an end tag, i.e. [tag] stuff [/tag]. A standalone tag has no end tag, as in [area href=somepage]. (Note that [page ...] and [order ..] are not container tags.)

For container tags (interpolated)

For standalone tags (reparsed)

(Note: The mixing of 'interpolate' and 'reparse' logic occurred because 'interpolate' already worked this way when 'reparse' was added to Interchange. This may be fixed in a later release...)

Most standalone tags are not reparsed by default (i.e., interpolate=0 by default). There are some exceptions, such as the [include] tag.

Interpolation example:

Assuming that name is 'Kilroy',

   [log interpolate=1][value name] was here[/log]
   [log interpolate=0][value name] was here[/log]

the first line logs 'Kilroy was here' to catalog_root/etc/log, while the second logs '[value name] was here'.

Reparsing example:

Suppose we set a scratch variable called 'now' as follows:

   [set name=now interpolate=0][time]%A, %B %d, %Y[/time][/set]

If today is Monday, January 1, 2001,

   [scratch name=now interpolate=0]
   [scratch name=now interpolate=1]

the first line yields

   [time]%A, %B %d, %Y[/time]

while the second yields

   Monday, January 1, 2001

1.1.4.2. reparse

If true ("reparse=1"), the server will process any tags in the text output by the reparsed tag.

Reparse applies only to container tags (those with an end tag). The interpolate attribute controls reparsing of the output of standalone tags (see above).

Most container tags will have their output re-parsed for more Interchange tags by default. If you wish to inhibit this behavior, you must explicitly set the attribute reparse to 0. Note that you will almost always want the default action. The only container ITL tag that doesn't have reparse set by default is [mvasp].

Example:

Assuming that name is 'Kilroy',

  1.   [perl reparse=0]
          my $tagname = 'value';
          return "[$tagname name] was here\n"
       [/perl]

  2.   [perl reparse=1]
          my $tagname = 'value';
          return "[$tagname name] was here\n"
       [/perl]

expands to

  1.   [value name] was here

  2.   Kilroy was here

1.1.4.3. send

Deprecated

1.1.5. Tag-specific Attributes

Each tag may accept additional named attributes which vary from tag to tag. Please see the entry for the tag in question for details about tag-specific attributes.

1.1.6. Attribute Arrays and Hashes

Some tags allow you to pass an array or hash as the value of an attribute. For an ordinary tag, the syntax is as follows:

    attribute.n=value

    attribute.hashkey=value

where n is an integer array index. Note that you cannot use both an array and a hash with the same attribute -- if you use attribute.n, you cannot also use attribute.key for the same attribute.

Here is an example of an attribute array:

    search.0="se=hammer
              fi=products
              sf=description"
    search.1="se=plutonium
              fi=products
              sf=comment"

The [page] tag, for example, treats a search specification array as a joined search, automatically adding the other relevant search fields, including the 'co=yes' to indicate a combined search (joined searches are described in the Interchange database documentation).

Note that it is up to the tag to handle an array or hash value properly. See the documentation for the specific tag before passing it an attribute array or hash value.

1.1.6.1. Perl calls

Before passing attributes to a tag, the Interchange parser would convert the above example to an anonymous array reference. It would use the resulting arrayref as the value for the 'search' attribute in this example.

If you were passing the above example directly to a tag routine within a [perl] block or a usertag, you must actually pass an anonymous array as the value of the attribute as follows:

    my $arrayref = [ "se=hammer/fi=products/sf=description",
                     "se=plutonium/fi=products/sf=description", ];

    $Tag->routine( { search => $arrayref, } );

Similarly to use a hash reference for the 'entry' attribute:

    my $hashref = { name   => "required",
                    date   => 'default="%B %d, %Y"', };

    $Tag->routine( { entry => $hashref } );