Tag is a basic functional unit in ITL — Interchange Tag Language. It is to Interchange what HTML tags are to a HTML page, or binary executables to an Unix shell.
As tags and their usage are explained under the ITL glossary entry, we are going to explain usertag inclusion in the Interchange server and usertag programming here.
Tags have traditionally been defined in
lib/Vend/Interpolate.pm
file in the Interchange source tree.
While some of the crucial tags are still defined there (search for
^sub tag_
in the file) to solve the chicken-or-egg
problem, new tags should be created as standalone files within the
code/
directory in the Interchange
source. This makes them more manageable and allows you to easily
"deactivate" unused tags and decrease IC;'s memory footprint (as
explained above).
Even though all Interchange tags are generally called tags or usertags, there are actually three types of tags: system tags, user tags and UI tags. There's no functional difference between them, but we've decided to introduce a rough distinction.
System tags (or core tags) are defined in
lib/Vend/Interpolate.pm
and
code/SystemTag/
in
Interchange source. They are used by core Interchange modules
(lib/Vend/*.pm
files) and are required for a
functional installation.
Some files have the extension .coretag
, and some
have the usual .tag
, but there's no difference.
(.tag
is preferred for your custom tags).
User tags are defined in
code/UserTag/
directory and
form a collection of commonly used Interchange tags. This is the most
common type and directly intended for custom catalog programming.
UI (User Interface) tags are defined in
code/UI_Tag/
directory and
form a collection of extra tags used by our Admin UI interface.
A catalog that is not running the Admin UI should, theoretically, be able
to do without the whole code/UI_Tag/
directory. However, as very useful tags are found within all three types,
the AccumulateCode
approach is preferred over this crude
directory-based selection.
Global usertags (defined at the Interchange server level) run directly under Interchange server permissions, without restrictions.
Catalog usertags (defined at the catalog level), however, run under safe restrictions to maximize security.
You should run all your custom tags at catalog-level and eventually
let some of the restrictions loose using SafeUntrap
configuration
directive. Run global usertags only when there is no other option, and
make sure your code is as resilient to arbitrary user input as possible.
Usertags are defined using the UserTag
config directive so,
obviously, they have to be defined in interchange.cfg
or catalog.cfg
, or files included
by those basic configuration files.
While you could add your own tags to the default Interchange directories
(within the code/
directory, as
explained) or even define them in interchange.cfg
or catalog.cfg
directly, it's generally
best if you create a
usertag/
directory (at a catalog
or global level), put your custom tags there, and include them in the
running configuration with the include usertag/*.tag
configuration directive.
Here's a classic hello world usertag example, containing all the relevant structural elements:
# Copyright YEAR COPYRIGHT-HOLDER-NAME EMAIL-OR-WEB-ADDRESS # Licensed under the GNU GPL v2. See file LICENSE for details. # $Id: usertag,v 1.4 2007-11-14 12:38:08 racke Exp $ UserTag hello-world Order name UserTag hello-world addAttr UserTag hello-world Version $Revision: 1.4 $ UserTag hello-world Routine <<EOR sub { my ($name, $opt) = @_; my $ret; $name ||= "world"; $name = ucfirst $name; if ( $_ = $opt->{surname} ) { $_ = ucfirst; $name .= " $_"; } $ret = "Hello, $name!"; return $ret; } EOR
After you install the usertag (as explained above), you can test it by using this sample HTML code:
<pre> The default name: [hello-world] Name "John": [hello-world john] Name "John", surname "Doe": [hello-world name=john surname=doe] </pre>
As you can see, each usertag is defined through a series of
UserTag
lines. All possible UserTag
options are
explained in the following section.
Recognized usertag options are defined as a Perl hash named
%tagCanon
in file lib/Vend/Config.pm
:
Group
ActionMap
ArrayCode
HashCode
CoreTag
SearchOp
Filter
FormAction
OrderCheck
UserTag
SystemTag
Widget
Alias — another name, an alias, for the tag.
UserTagALIASED-NAME
AliasNAME
UserTag time Version $Revision: 1.4 $ UserTag date Alias time
addAttr — pass a hash reference with all user-supplied tag attributes as last argument to the tag handling subroutine.
UserTagNAME
addAttr[VALUE]
UserTag benchmark addAttr (implies Yes) UserTag benchmark addAttr 1 UserTag benchmark addAttr 0
attrAlias — another name, an alias, for a tag's attribute.
UserTagNAME
attrAliasALIASED-ATTR-NAME
REAL-ATTR-NAME
UserTag meta-info Order table column key UserTag meta-info attrAlias col column
attrDefault
canNest
Description — embedded, one-line tag description.
UserTagNAME
DescriptionTEXT
UserTag uninstall_feature Description Uninstall feature installed with 'Feature' config directive. UserTag uninstall_feature Description <<EOD Uninstall feature installed with 'Feature' config directive. EOD
Override
Visibility
Help
Documentation — embedded tag documentation. This can be any free-form text, but sometimes it's handy to write the documentation in Perl POD syntax, as it allows the use of convenient pod2text and related commands to read the documentation.
UserTagNAME
DocumentationTEXT
UserTag tabbed-display Documentation <<EOD tabbed-display -- DHTML tabbed display ...... EOD
ExtraMeta
Gobble
hasEndTag — the tag has an end tag. In other words, the tag is a container.
UserTagNAME
hasEndTag[VALUE]
UserTag widget hasEndTag (implies Yes) UserTag widget hasEndTag 1 UserTag widget hasEndTag 0
Implicit
Interpolate — interpolate tag data. Due to a poor naming choice, this option behaves differently for non-container and container tags.
For non-container tags, it specifies whether tag output should be reparsed for more Interchange tags.
For container tags, it specifies whether tag
body should be interpolated before being passed
to the tag. Another option, NoReparse
then controls
whether final tag output should
be reparsed for more Interchange tags.
Interpolation is turned off by default.
UserTagNAME
Interpolate[VALUE]
UserTag table-organize Interpolate (implies Yes) UserTag table-organize Interpolate 1 UserTag table-organize Interpolate 0
InvalidateCache
isEndAnchor
noRearrange
Order
PosNumber — number of positional tag parameters. This option is not required as the number is automatically calculated from the Order
option.
UserTagNAME
PosNumberCOUNT
UserTag test Order opt1 opt2 opt3 UserTag test PosNumber 3
PosRoutine
MapRoutine
NoReparse — do not reparse output from container tags for more Interchange tags. This option has no effect on non-container tags.
Reparsing is turned on by default (NoReparse 0
).
UserTagNAME
NoReparse[VALUE]
UserTag either NoReparse (implies Yes) UserTag either NoReparse 1 UserTag either NoReparse 0
JavaScriptCheck
Required
Routine
Version