For more information... RTFM!
NAVIGATION
PAGES THAT LINK HERE
ACCOUNT LOGIN

You are not logged in

Powered by Interchange version 5.7.0

Interchange tag introduction

Introduction

Interchange tags use a style similar to HTML, but with "[square brackets]" replacing "<chevrons>".  Interchange tags are also similar to HTML in syntax, in that they accept parameters and that there are both standalone and container tags.  The parameters that can be passed are similar too (i.e. parameter="value").

Parameter syntax

Summary

Interchange tag parameter syntax examples
[tagname] Tag called with no parameters.
[tagname someval] Tag called with one positional parameter.
[tagname parameter=someval] Tag called with one named parameter.
[tagname parameter="the value"] Tag called with a space in the parameter value.
[tagname 1 2 3] Tag called with multiple positional parameters.
[tagname foo=1 bar=2 baz=3] Tag called with multiple named parameters.
[tagname foo=`2 + 2`] Tag called with a calculated parameter (quotes are backticks).
[tagname foo="[value bar]"] Tag called with another tag used to provide a parameter value.
[tagname] ...[/tagname] Container tag called with no parameters.
[tagname foo=1] ...[/tagname] Container tag called with a positional parameter.

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

Most tags can accept some positional parameters.  This makes parsing faster and, in most cases, is simpler to write.  The following is an example tag call:

[value city]

This tag causes Interchange to look in the user's form values hash and return the value of the "city" form parameter, which might have been set with the following:

City: <input type="text" name="city" value="">

Positional parameters cannot be derived from other Interchange tags.  For example, the following will not work:

[value [value formfield]]

If the named parameter syntax is used then parameters can contain other tags.  For example, the following will work:

[value name="[value formfield]"]

There are exceptions to the above rule when using list tags, such as [item-list], [loop], [query] and others.  These tags, and their exceptions, are explained on their corresponding pages.

Tags and parameter names are not case sensitive, so [VALUE NAME=something] and [value name=something] will be treated exactly the same.  The Interchange development convention is to type Interchange tags and parameters in lower case.  This makes pages and tags easier to read.

Some tags, such as [control-set] include a hyphen (-) in their name.  In these cases, an underscore (_) may be used if you prefer (i.e. [control_set]).  The two forms are interchangeable, except that an ending tag must match the tag (i.e. don't use [control-set]...[/control_set]).  Having said that, hyphens look better and are preferred (by me).

Note

Note

The exception to the above is when calling tags from Perl.  In this case, you must use underscores.  For instance, $Tag->control_set() is valid, whereas $Tag->control-set() is invalid.

Container tags

How the result of the tag is displayed depends upon whether it's a container or a standalone tag.  A standalone tag has no ending element.  For instance:

[value name]

A container tag has a closing tag (for example, "[tagname] ... [/tagname]").  The following code 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 shown in the following example:

[if value name]
    You have a name.
    I think your name is [value name].
[/if]

A container tag will have its output re-parsed for more Interchange tags by default.  To inhibit this behaviour, set the reparse to 0.  It has been found, however, that the default reparsing is almost always desirable.

The output of a standalone tag will not be re-interpreted for Interchange tags (with some exceptions, such as [include filename].

Most container tags will not have their contents interpolated (parsed for Interchange tags) before being passed the container text.  Exceptions include [calc], [currency] and [seti].  All container tags accept the interpolate=1 tag parameter which if set true, causes the interpretation to take place.  If the default is for a particular tag to interpolate its body text then passing an interpolate=0 parameter will inhibit this.

HTML-style comments

You are also allowed to use "<!--[" and "]-->" as interchangeable alternatives to plain square brackets, so [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 Interchange tags, when editing Interchange page templates.

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 "Kevin":

"<!--[value name]-->"    becomes  "Kevin"
"<!-- [value name] -->"  becomes  "<!-- Kevin -->"


Note

Note

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

To prevent Interchange tags from being interpolated at all, you can either set the no_html_comment_embed pragma, or enclose the block in a special [comment] container.  For example:

Left [comment] Middle [value name] [/comment] Right

becomes:

Left  Right

Besides not being interpolated, [comment] blocks do not appear in the final output text sent to the client, so you can be completely safe regarding any unintentional code or information leakage.

If you are modifying the special administrative interface pages and intend to use this syntax then see the Interchange tag parsing order section, below.

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 parameters.

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:

  • 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.
  • When there is some ambiguity as to which parameter is which, usually due to whitespace.
  • When you need to use the output of a tag as the parameter or attribute for another tag.

Note

Note

You cannot mix named and positional parameters in the same tag;  Parameters must be either all named, or all positional.  It seems this cannot be stressed enough, and remains a common beginners' mistake, especially when foreign code is copied, pasted and combined with existing code.

Interpolating parameters

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

[area scan se=[scratch somevar]]

To get the [scratch somevar] to be interpolated, and its result passed to the [area] tag, the parameter must be named and quoted, as follows:

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

The "href" parameter's value (scan) did not need to be quoted.  The "arg" parameter only needed to be quoted because its value contained whitespace.

Without the quotes, the whitespace would be taken to be a delimiter between individual parameters, which is the main reason why the uncorrected example would have failed to produce the desired result.

Note

Note

Only named parameters can be quoted to enclose whitespace in this way.  If one parameter is named then all parameters must be named.

Parameter quoting

Single and double quotes

Single (') and double quotes (") both have the same effect, and can be mixed to avoid confusion in the parser.  For example:

[value name="b_city" set="[value name='city' filter='strip']"]

Vertical bars (pipes)

Vertical bars (|), also known as pipes, can also be used as quoting characters, but have the unique behaviour of stripping leading and trailing whitespace.  For example:

[loop list="A1 A2 A3 B1 B2 B3"]
    [loop-increment][loop-code]
[/loop]

could be better expressed as:

[loop list=|
        A1    A2    A3
        B1    B2    B3
|]
    [loop-increment][loop-code]
[/loop]

Back-ticks

Back-ticks (`) should be used with extreme caution since they cause the parameter contents to be evaluated as Perl code, using the equivalent of a call to the [calc] tag.

For example: 

[value name=current_count set=`$Scratch->{counter}++`]

is the same as: 

[value name=current_count set="[calc]$Scratch->{counter}++[/calc]"]

Omitting quotes altogether

Exactly when can you omit the quotes around parameter values?

The first answer is trivial:  Never omit the quotes and you'll never run into trouble.

The other answer says "omitting quotes earns you a bonus for style and achieves small parser speed improvement." However, if the value contains whitespace then you must quote it.  To quote values, you can use double quotes ("), single quotes (') or vertical bars (|).  Vertical bars have the additional functionality of removing leading and trailing whitespace, but generally you can use all types in combination to do three levels of quoting with Interchange tags.  For more deeply nested constructs, use direct Perl code.

The above answers to the quoting problem, however, are still not all there is to know about quoting.  In general, loop sub-tags do not need quotes (even though they sometimes contain whitespace) because they are parsed in a separate pass, before the general parser gets to work.

Here's an example that would work properly with quotes omitted.  Pay attention to [item-field uri] which, at first sight, looks like it is invalid because it is not quoted and contains a space.

[item-list]
    <a href="[area [item-field uri]]">detailed info</a> on [item-description]
[/item-list]

[area [value mypage]] would not work because the [value] tag shown is not a loop sub-tag.

You might wonder why unquoted tags are even allowed.  The answer is performance;  If you have large lists of tags you can achieve significant speed-ups by using positional parameters.  Parsing and disassembling named parameters takes more CPU cycles to process.

Attribute arrays and hashes

Introduction

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

Array parameter

[example-tag attribute.0=value]

Hash parameter

[example-tag attribute.hashkey=value]
Warning

Warning

You cannot use both an array and a hash with the same parameter name.  For instance, If you use "attribute.n" then you cannot use the same "attribute" name as "attribute.key", and vice versa.

Here is an example of an attribute array, where "0" and "1" are array index values:

[example-tag
    search.0=|
        se=hammer
        fi=products
        sf=description
    |
    search.1=|
        se=plutonium
        fi=products
        sf=comment
    |
]

The [area] 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.  Coordinated and joined searches are described in the Interchange search engine documentation.

Note

Note

It is up to each individual tag to handle array or hash parameter values properly.  See the documentation for the specific tag before passing it an attribute array or hash value.  If the tag doesn't expect to receive a parameter array or hash value then it might not do what you expect if you pass it such a value.

Warning

Warning

Interchange 5.4.0 and later versions have access to a pragma called interpolate_itl_references, which instructs Interchange to look for ICML tags within reference-based parameters, and interpolate any it finds.  If this pragma is not used, or is not present in the Interchange version you're using, then the parameter value will be passed to the tag verbatim.

Perl calls

Before passing attributes to a tag, the Interchange tag 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 @array = (
    "se=hammer/fi=products/sf=description",
    "se=plutonium/fi=products/sf=description",
);
$Tag->example_tag({
    search => \@array,
});

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

my %hash = (
    name => "required",
    date => 'default="%d %B %Y"',
);
$Tag->example_tag({
    entry => \%hash,
});

Interchange tag parsing order

Standard parsing

Under normal circumstances, the template page containing tags and HTML is parsed in the following order:

  1. Any content in MV_AUTOLOAD is prepended to the template page.
  2. Any [pragma] tags anywhere in the text are processed, and the specified pragmas are set.
    • Since [pragma] tags are preprocessed before any other content, Reparse will not catch them, nor will they work if included in variables.  Also, the specified pragma will apply to the entire template (not just the section after the tag).
    • If you want to apply a pragma with a variable or only to part of a document, you must use [tag pragma="..."] instead.
  3. Variables (macros) are processed in the following order:
    1. @@VARNAME@@ global variables.
    2. @_VARNAME_@ local or global variables.
    3. __VARNAME__ local variables.
  4. Interchange comments are stripped.
  5. False-endtag macros.such as [/page] and [/order]) are replaced with "</a>".  (DEPRECIATED)
  6. "<!--[tagname]-->" escapes are converted to [tagname].
    • This can be a convenience for your HTML editor if it has trouble with tags using the standard [tagname] syntax.
    • However, if you want to HTML-comment out an Interchange tag in content that will be fed raw to a browser, you must include whitespace between the HTML comment delimiters and the tag, like this, "<!-- [tagname] -->".
    • This behaviour will be switched off if the no_html_comment_embed pragma is active.
  7. The main tag parser is called.
    • Some tags parse recursively (depending upon reparse and interpolate settings, of course).
    • Some tags (such as [loop]) process sub-tags in their contained body text.  Hence, the sub-tags are not handled recursively.
    • Some tags are interpreted in the Vend::Parse::start() subroutine.  You cannot call them with the $Tag->tagname() syntax.  They are:
  8. Image paths substitution on the HTML output occurs.

Nonstandard parsing within the admin interface

Parsing of content via the specialised [regenerate] usertag, included with the administrative interface, does not obey the above order.  The MV_AUTOLOAD and "<!--[tagname]-->" escapes are skipped.  There are some other more subtle differences as well.  In the very unlikely event that you need to check this in the source code, compare the interpolate_html() and cache_html() subroutines in Interpolate.pm.

Nonstandard parsing of sub-tags

Sub-tags are parsed within the containing array-list or hash-list context created by the containing tag.  See the Looping tags and sub-tags category.

  • All sub-tags, at an earlier precedence level, are treated before any in the next level.
  • Within the same level, tags are processed in the order they appear on the page.
  • Any standard tags are processed during "interpolate" (before) or "reparse" (after) phases of processing the containing tag.

Note

Note

Processing within a HASH or ARRAY list is actually done as a series of global regular expression substitutions on the page.  Each substitution replaces one tag with the output of the subroutine(s) associated with it.

Array list context

In array-list context, sub-tags are processed in the following order:

  1. Replace [PREFIX-include] sub-tag(s) with the content of the named file(s)
  2. Check for [PREFIX-line] and prepare for it if present (does not process [PREFIX-line] at this time).
  3. [PREFIX-sub] definitions processed.
  4. [if-PREFIX-*] sub-tag nesting resolved.
  5. [PREFIX-alternate] processed.
  6. [if-PREFIX-param] processed.
  7. [if-PREFIX-pos] processed.
  8. [PREFIX-pos] processed.
  9. [if-PREFIX-field] processed.
  10. [PREFIX-line] processed (preparations performed earlier).
  11. [PREFIX-increment] processed.
  12. [PREFIX-accessories] processed.
  13. [PREFIX-options] processed.
  14. [PREFIX-code] processed.
  15. [PREFIX-description] processed.
  16. [PREFIX-field] processed.
  17. [PREFIX-price] processed.
  18. [PREFIX-change] processed.
  19. [PREFIX-calc] processed.
  20. [PREFIX-exec] processed.
  21. [PREFIX-filter] processed.
  22. [PREFIX-last] processed.
  23. [PREFIX-next] processed.
  24. User's previous HTML widget "selected" settings restored.
  25. Reparse standard tags in output of above (if the container tag has reparse enabled).

Hash list context

In hash-list context, sub-tags are processed in the following order:

  1. Replace [PREFIX-include] sub-tag(s) with the content of the named file(s)
  2. [PREFIX-sub] definitions processed.
  3. [if-PREFIX-*] sub-tag nesting resolved.
  4. [PREFIX-alternate] processed.
  5. [PREFIX-line] processed.
  6. [if-PREFIX-param] processed.
  7. [if-PREFIX-field] processed.
  8. [if-PREFIX-modifier] processed ([if-PREFIX-param] is functionally identical except for the parse order).
  9. [PREFIX-increment] processed.
  10. [PREFIX-accessories] processed.
  11. [PREFIX-options] processed.
  12. [PREFIX-code] processed.
  13. [PREFIX-quantity] processed.
  14. [PREFIX-modifier] processed.
  15. [PREFIX-param] processed.
  16. [PREFIX-quantity-name] processed.
  17. [PREFIX-modifier-name] processed.
  18. [PREFIX-subtotal] processed.
  19. [PREFIX-discount-subtotal] processed.
  20. [PREFIX-code] processed again (operating on new instances of [PREFIX-code] in the output of the above).
  21. [PREFIX-field] processed.
  22. [PREFIX-description] processed.
  23. [PREFIX-price] processed.
  24. [PREFIX-discount-price] processed.
  25. [PREFIX-difference] processed.
  26. [PREFIX-discount] processed.
  27. [PREFIX-change] processed.
  28. [PREFIX-calc] processed.
  29. [PREFIX-exec] processed.
  30. [PREFIX-filter] processed.
  31. [PREFIX-last] processed.
  32. [PREFIX-next] processed.
  33. User's previous HTML widget "selected" settings restored.
  34. Reparse standard tags in output of above (if the container tag has reparse enabled).
Last modified by: Kevin Walsh
Modification date: Monday 17 September 2007 at 1:39 AM (EDT)
Home  |  Legal nonsense  |  Privacy policy  |  Donations  |  Contact us