Why not adopt me?
NAME
HTML::Transmorgify::Metatags - Template language processor
SYNOPSIS
use HTML::Transmorgify;
my $magic = HTML::Transmorgify->new(xml_quoting => 1);
$magic->mixin('HTML::Transmorgify::Metatags');
my $output = $magic->process($input_text, { %options }, %variables);
use HTML::Transmorgify::Metatags qw(%transformations);
use HTML::Transmorgify::Metatags qw(@include_dirs);
use HTML::Transmorgify::Metatags qw(%allowed_functions);
DESCRIPTION
HTML::Transmorgify::Metatags provices an HTML-esque template language for transforming HTML.
HTML::Transmorgify is a framework for compiling HTML transformations and HTML::Transmorgify::Metatags uses it to compile the template transformations. Applying the transformations is a two step process with a compile-time part and a run-time part. Compiled templates are cached so a second invocation of the same template will skip the compile-time part.
HTML::Transmorgify::Metatags does not provide an escape-to-perl mechenism for template writers. Instead template writers are considered to be only semi-trusted (by default they can embed javascript) and real programming is expected to be done either outside the template system or by creating add-on modules for the template system to use.
HTML::Transmorgify::Metatags directives look like regular HMTL tags. They are interpreted by HTML::Transmorgify and are not included in the final output stream.
MACROS
The <macro>
tag is used to expand a variable or macro. The form of the call is:
<macro VAR_NAME>
<macro name=VAR_NAME>
<macro name=VAR_NAME encode=ENCODING=>
Macro expansions can be done inside attribute values of other tags:
<img alt="<macro alttag>">
Some macro values are evaluated at runtime. These might in turn use other macros. All named attributes to a <macro> are added as temporary macros while doing a lookup.
Defining Macro Values
Macro values can be set in the invocation of HTML::Transmorgify:
my $output = $magic->process($input_text, { %options },
alt_tag => 'my image',
my_title => 'yea, we did it',
an_array => [ 'foo', 'bar' ],
a_hash => { foo => 'bar' },
an_object => $object,
);
If a macro name has periods in it, then variable is expected to be a complex object or structure. For example, if the variable name is an_array.1
then first an_array
would be looked up. Assuming that what's found is a object, array, or hash, then 1
would be looked up in the result. With the values initialized in the previous example, the result would be bar
.
When a variable refers to an object, if there are additional elements to the variable name, they will be looked up by using the lookup
method. If there are no additional elements to refine the lookup, then the object is turned to text with the text
method.
A virtual base clase that objects can inherit from is defined in HTML::Transmorgify::ObjectGlue.
Macros can also be defined with the <define>
directive. All of these do the same thing:
<define title>my new title</define>
<define name="title">my new title</define>
<define title value="my new title" />
<define name="title" value="my new title" />
The <define> tag uses some attributes to control it's behavior:
- eval
-
Normally, <define> values are evaluated at runtime. If you know that the value is never going to change, then you can use the
eval
attribute set to false to force the value to be evaluated and locked in at compile time. This can provide a performance boost. Settingeval=false
can have bad consequences if the values change.<define fullname><macro firstname> <macro lastname></define>
Compile-time only happens once so if
firstname
andlastname
are parameters that change from invocation to invocation, evaluating them should be deferred until runtime by using theeval="true"
attribute. - name
-
The name of the Macro being defined.
- value
-
The text of the new defintion.
- trim
-
The trim attribute will eleminate some of the whitespace from within the new value:
- start
-
Trims whitespace from the beginning of the definition
- end
-
Trims whitespace from the end of the definition
- all
-
Trims whitespace from both ends of all text blocks within the definition. The only things that are not text blocks are other tags that compile to something other than literal text. For example, another <define> tag.
All attribute values of the <define> tag become temporary overrides (local variables) for that define.
<define firstname>John</define>
<define middlename>Fredricks</define>
<define lastname>Smith</define>
<define name lastname="Jones" eval=1><macro firstname> <macro middlename> <macro lastname></define>
<macro name middlename="Simon" lastname="Barney">
The output from this will be John Simon Johnes
. The firstname is John
because that is the only value it gets. The middle name is Simon
because it is overridden in the <macro> invocation. The last name is Jones
because the it is overriden twice: first in the macro invocation and then in the definition of the name
<macro>.
Transformations
When a <macro>
is expanded, the new value can be transformed. The syntax is
<macro macro_name encode="ENCODING">
Where ENCODING
is one of the following:
- html
-
Substitute
<
for<
and>
for>
and all similar HTMl entity transformations handled by HTML::Entities. This is the default transformation. Useencode="none"
if you do not want this.
- uri / url
-
Encode for a URL: Substitute
%20
for space and all the rest of the substitutions handled by URI::Escape. - comment
-
Throw away the value and return the empty string. XXX currently this still evaluates things within the comment, it's just the final result that is tossed. XXX add a <silent> or <empty> tag to supplant the current <comment> and have <comment> ignore its contents.
- none
-
Pass the expanded value through unchanged.
Transformations can also be invoked on any section of input text using the >transform<
tag.
<transform html>Really sloppy stuff with <> and the like.</transform>
<transform encode=url>http://my.url/with spaces in it</transform>
Additional transformations can be added by modifying the hash %HTML::Transmorgify::Metatags::transformations
which is exported by request.
CONTROL FLOW
HTML::Transmorgify::Metatags also provides control flow directives: conditionals, loops, and include files.
<if> <elsif> <else>
There are two ways to write the conditional for an <if>
tag:
<if is_set="MACRO_NAME">
<if expr="<macro age> < 18">
The is_set
test is true if the macro variable MACRO_NAME
is set to a non-empty string.
The expr
test supports a syntax that closely matches the expresssion syntax supported by perl. It is not evaluated with perl's eval
but rather the expression is parsed at compile time and evaluated at runtime using a grammer.
The grammer includes calling functions. Only the functions defined in %HTML::Transmorgify::Metatags::allowed_functions
(exported on request) are allowed. Add more to that hash if you need them.
The pre-defined functions are:
- abs()
-
absolute value
- defined()
-
value is defined
- min()
-
From List::Util
- max()
-
From List::Util
The <if>
block finishes with
</if>
<elsif>
and <else>
are optional and do not have their own closing tags.
<foreach varname container(s) [assignments]>
The <foreach>
tag provides looping.
The first parameter for <foreach>
is the name of the macro that will change with each iteration. This can also be set with var=SOME_NAME
.
All suceeding parameters that are of the form of just an attribute name (without an equals sign for an attribute value) will be treated as macros that will be expanded into lists (if they can be). The resulting values from these expansions is what will be looped over in the <foreach>.
If there are no such parameters then <foreach> will look for a container=
parameter.
Any additional attributes with values will be temporary overrides to macros.
When looping over a hash, <macro varname>
will be set to each of the values in turn. When looping over an array, it will be set to each of the values in turn. The keys from a hash will be available as <macro _varname>
(notice the underscore). The index positions from ann array will be <macro _varname>
.
<include>
The <include> tag incoporates the contents of another file into the current output. The name of the file can be specified as either the first attribute of the <include> tag or as the named attribute file
. Both of the following examples do the same thing:
<include body.inc>
<include file="body.inc">
The filename must be a relative path.
Files are searched for by traversing the array @HTML::Transmorgify::Metatags::include_dirs
which is exported by request. If any elements in that array are CODE references, then they will be invoked with the filename that is being searched for as an argument. Their return value should be undef or a filename.
DIVERSIONS
HTML::Transmorgify::Metatags provides diversions. The macros that control this are <capture>
and <playback>
. What is capture'd is removed from the normal output flow of the document. It can be included somewhere else with <playback>
. Diversions do not effect the runtime execution order so the text for a capture will be captured sequenced as if the capture didn't exist.
For example you have:
Before
<define x value=before>
<capture A>
A
x1=<macro x>
<define x value=A>
x2=<macro x>
</capture A>
After
x3=<macro x>
<define x value=after>
<playback A />
You'll get:
Before
After
x3=A
A
x1=before
x2=A
Diversions are resolved as a post-processing step so the <capture>
and <playback>
tags can be used in nearly any order. You can <playback>
a diverison before it is saved wtih <capture>
.
A <playback>
inside a <capture>
creates a dependency: the playback'ed diversion must be resolved before the catpure'd diversion. Circular dependencies are not allowed.
RESERVED WORDS
The following macros/variables are reserved for future use and should not be used at the current time:
_diversions
_current_diversion