|
|
expr
node(name)
nodelist(name)
exprOrNode(name,attrname,attrvalue)
exprOrNodelist(name,attrname,attrvalue)
struct
Apache::AxKit::XSP::Language::SimpleTaglib - alternate XSP taglib helper
package Your::XSP::Package; use Apache::AxKit::Language::XSP::SimpleTaglib;
... more initialization stuff, start_document handler, utility functions, whatever you like, but no parse_start/end handler needed - if in doubt, just leave empty ...
package Your::XSP::Package::Handlers;
sub some_tag : attrib(id) attribOrChild(some-param) node(result) keepWhitespace { my ($e, $tag, %attr) = @_; return 'do_something($attr_some_param,'.$attr{'id'}.');'; }
This taglib helper allows you to easily write tag handlers with most of the common behaviours needed. It manages all 'Design Patterns' from the XSP man page plus several other useful tag styles.
A tag ``<yourNS:foo>'' will trigger a call to sub ``foo'' during the closing tag event. What happens in between can be configured in many ways using function attributes. In the rare cases where some action has to happen during the opening tag event, you may provide a sub ``foo__open'' (double underscore) which will be called at the appropriate time. Usually you would only do that for 'if'- style tags which enclose some block of code.
A sub named ``foo___bar'' (triple underscore) gets called on the following XML input: ``<yourNS:foo><yourNS:bar/></yourNS:foo>''. Handler subs may have any nesting depth. The rule for opening tag handlers applies here as well. The sub name must represent the exact tag hierarchy (within your namespace).
Names for subs and variables get created by replacing any non-alphanumeric character in the original tag or attribute to underscores. For example, 'get-id' becomes 'get_id'.
The called subs get passed 3 parameters: The parser object, the tag name, and an attribute hash. This hash only contains XML attributes declared using the 'attrib()' function attribute. (Try not to confuse these two meanings of 'attribute' - unfortunately XML and Perl both call them that way.) All other declared parameters get converted into local variables with prefix 'attr_'.
If a sub has any result attribute ('node', 'expr', etc.), it gets called in list context. If neccessary, returned lists get converted to scalars by joining them without separation. Plain subs (without result attribute) inherit their context and have their return value left unmodified.
If more than one handler matches a tag, the following rules determine which one is chosen. Remember, though, that only tags in your namespace are considered.
Apache::AxKit::Language::XSP contains a few handy utility subs:
Parameters to attributes get handled as if 'q()' enclosed them. Commas separate arguments, so values cannot contain commas.
Choose none or one of these to select output behaviour.
expr
Makes this tag behave like an '<xsp:expr>' tag, creating text nodes or inline text as appropriate. Choose this if you create plain text which may be used everywhere, including inside code. This attribute has no parameters.
node(name)
Makes this tag create an XML node named name
. The tag encloses all content as well as the
results of the handler sub.
Choose this if you want to create one XML node with all your output.
nodelist(name)
Makes this tag create a list of XML nodes named name
. The tag(s)
do not enclose content nodes,
which become preceding siblings of the generated nodes. The return value gets converted to a
node list by enclosing each element with an XML node named name
.
Choose this if you want to create a list of uniform XML nodes with all your output.
exprOrNode(name,attrname,attrvalue)
Makes this tag behave described under either 'node()' or 'expr', depending on the value of
XML attribute attrname
. If that value matches attrvalue
, it will work like 'node()',
otherwise it will work like 'expr'. attrname
defaults to 'as', attrvalue
defaults to
'node', thus leaving out both parameters means that 'as=``node''' will select 'node()' behaviour.
Choose this if you want to let the XSP author decide what to generate.
exprOrNodelist(name,attrname,attrvalue)
Like exprOrNode, selecting between 'expr' and 'nodelist()' behaviour.
struct
Makes this tag create a more complex XML fragment. You may return a single hashref or an array of hashrefs, which get converted into an XML structure. Each hash element may contain a scalar, which gets converted into an XML tag with the key as name and the value as content. Alternatively, an element may contain an arrayref, which means that an XML tag encloses each single array element. Finally, you may use hashrefs in place of scalars to create substructures. To create attributes on tags, use a hashref that contain the attribute names prefixed by '@'. A '' (empty string) as key denotes the text contents of that node.
In an expression context, passes on the unmodified return value.
These may appear more than once and modify output behaviour.
nodeAttr(name,expr,...)
Adds an XML attribute named name
to all generated nodes. expr
gets evaluated at run time.
Evaluation happens once for each generated node. Of course, this tag only makes sense with
'node()' type handlers.
These tags specify how input gets handled. Most may appear more than once, if that makes sense.
attrib(name,...)
Declares name
as a (non-mandatory) XML attribute. All attributes declared this way get
passed to the handler subs in the attribute hash.
child(name,...)
Declares a child tag name
. It always lies within the same namespace as the taglib itself. The
contents of the tag, if any, get saved in a local variable named $attr_name
. If the child tag
appears more than once, the last value overrides any previous value.
attribOrChild(name,...)
Declares an attribute or child tag named name
. A variable is created just like for 'child()',
containing the attribute or child tag contents. If both appear, the contents of the child tag take
precedence.
keepWhitespace
Makes this tag preserve contained whitespace.
captureContent
Makes this tag store the enclosed content in '$_' for later retrieval in the handler sub, instead of adding it to the enclosing element. Non-text nodes will not work as expected.
childStruct(spec)
Marks this tag to take a complex xml fragment as input. The resulting data structure is available as %_ in the sub. Whitespace is always preserved.
spec
has the following syntax:
spec
consists of a list of tag names, separated by whitespace.spec
and a
closing '}' must follow.Example:
sub:
set_permission : childStruct(add{@permission{$type *name} $target $comment(lang)(day)} remove{@permission{$type *name} $target})
XML:
<set-permission> <add> <permission type="user"> foo </permission> <permission> <type>group</type> bar </permission> <target>/test.html</target> <comment lang="en" day="Sun">Test entry</comment> <comment lang="en" day="Wed">Test entry 2</comment> <comment><lang>de</lang>Testeintrag</comment> </add> <remove target="/test2.html"> <permission type="user"> baz </permission> </remove> </set-permission>
Result: a call to set_permission with %_ set like this:
%_ = ( add => { permission => [ { type => "user", name => 'foo' }, { type => "group", name => 'bar' }, ], target => '/test.html', comment => { 'en' => { 'Sun' => 'Test entry', 'Wed' => 'Test entry 2' }, 'de' => { '' => 'Testeintrag' }, } }, remove => { permission => [ { type => "user", name => 'baz' }, ], target => '/test2.html', }, );
See AxKit::XSP::Sessions and AxKit::XSP::Auth source code for full-featured examples.
Because of the use of perl attributes, SimpleTaglib will only work with Perl 5.6.0 or later. This software is already tested quite well and works for a number of simple and complex taglibs. Still, you may have to experiment with the attribute declarations, as the differences can be quite subtle but decide between 'it works' and 'it doesn't'. XSP can be quite fragile if you start using heavy trickery.
If some tags don't work as expected, try surrounding the offending tag with <xsp:content>, this is a common gotcha (but correct and intended). If you find yourself needing <xsp:expr> around a tag, please contact the author, as that is probably a bug.
Jörg Walter <jwalt@cpan.org>
Copyright (c) 2002 Jörg Walter. Documentation All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as AxKit itself.
AxKit, Apache::AxKit::Language::XSP, Apache::AxKit::Language::XSP::TaglibHelper