.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.42) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "Template::Declare::Tags 3pm" .TH Template::Declare::Tags 3pm "2022-06-17" "perl v5.34.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Template::Declare::Tags \- Build and install XML Tag subroutines for Template::Declare .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& package MyApp::Templates; \& \& use base \*(AqTemplate::Declare\*(Aq; \& use Template::Declare::Tags \*(AqHTML\*(Aq; \& \& template main => sub { \& link {} \& table { \& row { \& cell { "Hello, world!" } \& } \& } \& img { attr { src => \*(Aqcat.gif\*(Aq } } \& img { src is \*(Aqdog.gif\*(Aq } \& }; .Ve .PP Produces: .PP .Vb 8 \& \& \& \& \& \&
Hello, world!
\& \& .Ve .PP Using \s-1XUL\s0 templates with a namespace: .PP .Vb 1 \& package MyApp::Templates; \& \& use base \*(AqTemplate::Declare\*(Aq; \& use Template::Declare::Tags \& \*(AqXUL\*(Aq, HTML => { namespace => \*(Aqhtml\*(Aq }; \& \& template main => sub { \& groupbox { \& caption { attr { label => \*(AqColors\*(Aq } } \& html::div { html::p { \*(Aqhowdy!\*(Aq } } \& html::br {} \& } \& }; .Ve .PP Produces: .PP .Vb 7 \& \& \& \& howdy! \& \& \& .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\f(CW\*(C`Template::Declare::Tags\*(C'\fR is used to generate templates and install subroutines for tag sets into the calling namespace. .PP You can specify the tag sets to install by providing a list of tag modules in the \f(CW\*(C`use\*(C'\fR statement: .PP .Vb 1 \& use Template::Declare::Tags qw/ HTML XUL /; .Ve .PP By default, Template::Declare::Tags uses the tag set provided by Template::Declare::TagSet::HTML. So .PP .Vb 1 \& use Template::Declare::Tags; .Ve .PP is equivalent to .PP .Vb 1 \& use Template::Declare::Tags \*(AqHTML\*(Aq; .Ve .PP Currently Template::Declare bundles the following tag sets: Template::Declare::TagSet::HTML, Template::Declare::TagSet::XUL, Template::Declare::TagSet::RDF, and Template::Declare::TagSet::RDF::EM. .PP You can specify your own tag set classes, as long as they subclass Template::Declare::TagSet and implement the corresponding methods (e.g. \&\f(CW\*(C`get_tag_list\*(C'\fR). .PP If you implement a custom tag set module named \&\f(CW\*(C`Template::Declare::TagSet::Foo\*(C'\fR, you can load it into a template module like so: .PP .Vb 1 \& use Template::Declare::Tags \*(AqFoo\*(Aq; .Ve .PP If your tag set module is not under the Template::Declare::TagSet namespace, use the \&\f(CW\*(C`from\*(C'\fR option to load it. Fore example, if you created a tag set named \&\f(CW\*(C`MyTag::Foo\*(C'\fR, then you could load it like so: .PP .Vb 1 \& use Template::Declare::Tags Foo => { from => \*(AqMyTag::Foo\*(Aq }; .Ve .PP \&\s-1XML\s0 namespaces are emulated by Perl packages. For example, to embed \s-1HTML\s0 tags within \s-1XUL\s0 using the \f(CW\*(C`html\*(C'\fR namespace: .PP .Vb 1 \& package MyApp::Templates; \& \& use base \*(AqTemplate::Declare\*(Aq; \& use Template::Declare::Tags \*(AqXUL\*(Aq, HTML => { namespace => \*(Aqhtml\*(Aq }; \& \& template main => sub { \& groupbox { \& caption { attr { label => \*(AqColors\*(Aq } } \& html::div { html::p { \*(Aqhowdy!\*(Aq } } \& html::br {} \& } \& }; .Ve .PP This will output: .PP .Vb 7 \& \& \& \& howdy! \& \& \& .Ve .PP Behind the scenes, \f(CW\*(C`Template::Declare::Tags\*(C'\fR generates a Perl package named \&\f(CW\*(C`html\*(C'\fR and installs the \s-1HTML\s0 tag subroutines into that package. On the other hand, \s-1XUL\s0 tag subroutines are installed into the current package, namely, \&\f(CW\*(C`MyApp::Templates\*(C'\fR in the previous example. .PP There may be cases when you want to specify a different Perl package for a particular \s-1XML\s0 namespace. For instance, if the \f(CW\*(C`html\*(C'\fR Perl package has already been used for other purposes in your application and you don't want to install subs there and mess things up, use the \f(CW\*(C`package\*(C'\fR option to install them elsewhere: .PP .Vb 6 \& package MyApp::Templates; \& use base \*(AqTemplate::Declare\*(Aq; \& use Template::Declare::Tags \*(AqXUL\*(Aq, HTML => { \& namespace => \*(Aqhtm\*(Aq, \& package => \*(AqMyHtml\*(Aq \& }; \& \& template main => sub { \& groupbox { \& caption { attr { label => \*(AqColors\*(Aq } } \& MyHtml::div { MyHtml::p { \*(Aqhowdy!\*(Aq } } \& MyHtml::br {} \& } \& }; .Ve .PP This code will generate something like the following: .PP .Vb 7 \& \& \& \& howdy! \& \& \& .Ve .SH "METHODS AND SUBROUTINES" .IX Header "METHODS AND SUBROUTINES" .SS "Declaring templates" .IX Subsection "Declaring templates" \fItemplate \s-1TEMPLATENAME\s0 => sub { 'Implementation' };\fR .IX Subsection "template TEMPLATENAME => sub { 'Implementation' };" .PP .Vb 6 \& template select_list => sub { \& my $self = shift; \& select { \& option { $_ } for @_; \& } \& }; .Ve .PP Declares a template in the current package. The first argument to the template subroutine will always be a \f(CW\*(C`Template::Declare\*(C'\fR object. Subsequent arguments will be all those passed to \f(CW\*(C`show()\*(C'\fR. For example, to use the above example to output a select list of colors, you'd call it like so: .PP .Vb 1 \& Template::Declare\->show(\*(Aqselect_list\*(Aq, qw(red yellow green purple)); .Ve .PP You can use any URL-legal characters in the template name; \&\f(CW\*(C`Template::Declare\*(C'\fR will encode the template as a Perl subroutine and stash it where \f(CW\*(C`show()\*(C'\fR can find it. .PP (Did you know that you can have characters like \*(L":\*(R" and \*(L"/\*(R" in your Perl subroutine names? The easy way to get at them is with \f(CW\*(C`can\*(C'\fR). .PP \fIprivate template \s-1TEMPLATENAME\s0 => sub { 'Implementation' };\fR .IX Subsection "private template TEMPLATENAME => sub { 'Implementation' };" .PP .Vb 6 \& private template select_list => sub { \& my $self = shift; \& select { \& option { $_ } for @_; \& } \& }; .Ve .PP Declares that a template isn't available to be called directly from client code. The resulting template can instead only be called from the package in which it's created. .SS "Showing templates" .IX Subsection "Showing templates" \fIshow [$template_name or \f(CI$template_coderef\fI], args\fR .IX Subsection "show [$template_name or $template_coderef], args" .PP .Vb 1 \& show( main => { user => \*(AqBob\*(Aq } ); .Ve .PP Displays templates. The first argument is the name of the template to be displayed. Any additional arguments will be passed directly to the template. .PP \&\f(CW\*(C`show\*(C'\fR can either be called with a template name or a package/object and a template. (It's both functional and \s-1OO.\s0) .PP If called from within a Template::Declare subclass, then private templates are accessible and visible. If called from something that isn't a Template::Declare, only public templates will be visible. .PP From the outside world, users can either call \f(CW\*(C`Template::Declare\->show()\*(C'\fR, \&\f(CW\*(C`show()\*(C'\fR exported from Template::Declare::Tags or \&\f(CW\*(C`Template::Declare::Tags::show()\*(C'\fR directly to render a publicly visible template. .PP Private templates may only be called from within the \f(CW\*(C`Template::Declare\*(C'\fR package. .PP \fIshow_page\fR .IX Subsection "show_page" .PP .Vb 1 \& show_page( main => { user => \*(AqBob\*(Aq } ); .Ve .PP Like \f(CW\*(C`show()\*(C'\fR, but does not dispatch to private templates. It's used internally by \f(CW\*(C`show()\*(C'\fR when when that method is called from outside a template class. .SS "Attributes" .IX Subsection "Attributes" \fIattr \s-1HASH\s0\fR .IX Subsection "attr HASH" .PP .Vb 1 \& attr { src => \*(Aqlogo.png\*(Aq }; .Ve .PP Specifies attributes for the element tag in which it appears. For example, to add a class and \s-1ID\s0 to an \s-1HTML\s0 paragraph: .PP .Vb 7 \& p { \& attr { \& class => \*(Aqgreeting text\*(Aq, \& id => \*(Aqwelcome\*(Aq, \& }; \& \*(AqThis is a welcoming paragraph\*(Aq; \& } .Ve .PP \fI\s-1ATTR\s0 is \s-1VALUE\s0\fR .IX Subsection "ATTR is VALUE" .PP Attributes can also be specified by using \f(CW\*(C`is\*(C'\fR, as in .PP .Vb 5 \& p { \& class is \*(Aqgreeting text\*(Aq; \& id is \*(Aqwelcome\*(Aq; \& \*(AqThis is a welcoming paragraph\*(Aq; \& } .Ve .PP A few tricks work for 'is': .PP .Vb 2 \& http_equiv is \*(Aqfoo\*(Aq; # => http\-equiv="foo" \& xml_\|_lang is \*(Aqfoo\*(Aq; # => xml:lang="foo" .Ve .PP So double underscore replaced with colon and single underscore with dash. .PP \fIwith\fR .IX Subsection "with" .PP .Vb 2 \& with ( id => \*(Aqgreeting\*(Aq, class => \*(Aqfoo\*(Aq ), \& p { \*(AqHello, World wide web\*(Aq }; .Ve .PP An alternative way to specify attributes for a tag, just for variation. The standard way to do the same as this example using \f(CW\*(C`attr\*(C'\fR is: .PP .Vb 2 \& p { attr { id => \*(Aqgreeting\*(Aq, class => \*(Aqfoo\*(Aq } \& \*(AqHello, World wide web\*(Aq }; .Ve .SS "Displaying text and raw data" .IX Subsection "Displaying text and raw data" \fIouts \s-1STUFF\s0\fR .IX Subsection "outs STUFF" .PP .Vb 1 \& p { outs \*(AqGrettings & welcome pyoonie hyoomon.\*(Aq } .Ve .PP HTML-encodes its arguments and appends them to \f(CW\*(C`Template::Declare\*(C'\fR's output buffer. This is similar to simply returning a string from a tag function call, but is occasionally useful when you need to output a mix of things, as in: .PP .Vb 1 \& p { outs \*(Aqhello\*(Aq; em { \*(Aqworld\*(Aq } } .Ve .PP \fIouts_raw \s-1STUFF\s0\fR .IX Subsection "outs_raw STUFF" .PP .Vb 1 \& p { outs_raw "That\*(Aqs what I\*(Aqm talking about!\*(Aq } .Ve .PP Appends its arguments to \f(CW\*(C`Template::Declare\*(C'\fR's output buffer without \s-1HTML\s0 escaping. .SS "Installing tags and wrapping stuff" .IX Subsection "Installing tags and wrapping stuff" \fIinstall_tag \s-1TAGNAME, TAGSET\s0\fR .IX Subsection "install_tag TAGNAME, TAGSET" .PP .Vb 1 \& install_tag video => \*(AqTemplate::Declare::TagSet::HTML\*(Aq; .Ve .PP Sets up \s-1TAGNAME\s0 as a tag that can be used in user templates. \s-1TAGSET\s0 is an instance of a subclass for Template::Declare::TagSet. .PP \fIsmart_tag_wrapper\fR .IX Subsection "smart_tag_wrapper" .PP .Vb 3 \& # create a tag that has access to the arguments set with L. \& sub sample_smart_tag (&) { \& my $code = shift; \& \& smart_tag_wrapper { \& my %args = @_; # set using \*(Aqwith\*(Aq \& outs( \*(Aqkeys: \*(Aq . join( \*(Aq, \*(Aq, sort keys %args) . "\en" ); \& $code\->(); \& }; \& } \& \& # use it \& with ( foo => \*(Aqbar\*(Aq, baz => \*(Aqbundy\*(Aq ), sample_smart_tag { \& outs( "Hello, World!\en" ); \& }; .Ve .PP The output would be .PP .Vb 2 \& keys: baz, foo \& Hello, World! .Ve .PP The smart tag wrapper allows you to create code that has access to the attribute arguments specified via \f(CW\*(C`with\*(C'\fR. It passes those arguments in to the wrapped code in \f(CW@_\fR. It also takes care of putting the output in the right place and tidying up after itself. This might be useful to change the behavior of a template based on attributes passed to \f(CW\*(C`with\*(C'\fR. .PP \fIcreate_wrapper \s-1WRAPPERNAME\s0 => sub { 'Implementation' };\fR .IX Subsection "create_wrapper WRAPPERNAME => sub { 'Implementation' };" .PP .Vb 7 \& create_wrapper basics => sub { \& my $code = shift; \& html { \& head { title { \*(AqWelcome\*(Aq } }; \& body { $code\->() } \& } \& }; .Ve .PP \&\f(CW\*(C`create_wrapper\*(C'\fR declares a wrapper subroutine that can be called like a tag sub, but can optionally take arguments to be passed to the wrapper sub. For example, if you wanted to wrap all of the output of a template in the usual \&\s-1HTML\s0 headers and footers, you can do something like this: .PP .Vb 3 \& package MyApp::Templates; \& use Template::Declare::Tags; \& use base \*(AqTemplate::Declare\*(Aq; \& \& BEGIN { \& create_wrapper wrap => sub { \& my $code = shift; \& my %params = @_; \& html { \& head { title { outs "Hello, $params{user}!"} }; \& body { \& $code\->(); \& div { outs \*(AqThis is the end, my friend\*(Aq }; \& }; \& } \& }; \& } \& \& template inner => sub { \& wrap { \& h1 { outs "Hello, Jesse, s\*(Aqup?" }; \& } user => \*(AqJesse\*(Aq; \& }; .Ve .PP Note how the \f(CW\*(C`wrap\*(C'\fR wrapper function is available for calling after it has been declared in a \f(CW\*(C`BEGIN\*(C'\fR block. Also note how you can pass arguments to the function after the closing brace (you don't need a comma there!). .PP The output from the \*(L"inner\*(R" template will look something like this: .PP .Vb 9 \& \& \& Hello, Jesse! \& \& \&

Hello, Jesse, s'up?

\&
This is the end, my friend
\& \& .Ve .SS "Helpers" .IX Subsection "Helpers" \fIxml_decl \s-1HASH\s0\fR .IX Subsection "xml_decl HASH" .PP .Vb 1 \& xml_decl { \*(Aqxml\*(Aq, version => \*(Aq1.0\*(Aq }; .Ve .PP Emits an \s-1XML\s0 declaration. For example: .PP .Vb 2 \& xml_decl { \*(Aqxml\*(Aq, version => \*(Aq1.0\*(Aq }; \& xml_decl { \*(Aqxml\-stylesheet\*(Aq, href => "chrome://global/skin/", type => "text/css" }; .Ve .PP Produces: .PP .Vb 2 \& \& .Ve .PP \fIcurrent_template\fR .IX Subsection "current_template" .PP .Vb 1 \& my $path = current_template(); .Ve .PP Returns the absolute path of the current template .PP \fIcurrent_base_path\fR .IX Subsection "current_base_path" .PP .Vb 1 \& my $path = current_base_path(); .Ve .PP Returns the absolute base path of the current template .PP \fIunder\fR .IX Subsection "under" .PP \&\f(CW\*(C`under\*(C'\fR is a helper function providing semantic sugar for the \f(CW\*(C`mix\*(C'\fR method of Template::Declare. .PP \fIsetting\fR .IX Subsection "setting" .PP \&\f(CW\*(C`setting\*(C'\fR is a helper function providing semantic sugar for the \f(CW\*(C`mix\*(C'\fR method of Template::Declare. .SH "VARIABLES" .IX Header "VARIABLES" .ie n .IP "@Template::Declare::Tags::EXPORT" 4 .el .IP "\f(CW@Template::Declare::Tags::EXPORT\fR" 4 .IX Item "@Template::Declare::Tags::EXPORT" Holds the names of the static subroutines exported by this class. Tag subroutines generated by tag sets, however, are not included here. .ie n .IP "@Template::Declare::Tags::TAG_SUB_LIST" 4 .el .IP "\f(CW@Template::Declare::Tags::TAG_SUB_LIST\fR" 4 .IX Item "@Template::Declare::Tags::TAG_SUB_LIST" Contains the names of the tag subroutines generated from a tag set. .Sp Note that this array won't get cleared automatically before another \&\f(CW\*(C`use Template::Decalre::Tags\*(C'\fR statement. .Sp \&\f(CW@Template::Declare::Tags::TagSubs\fR is aliased to this variable for backward-compatibility. .ie n .IP "$Template::Declare::Tags::TAG_NEST_DEPTH" 4 .el .IP "\f(CW$Template::Declare::Tags::TAG_NEST_DEPTH\fR" 4 .IX Item "$Template::Declare::Tags::TAG_NEST_DEPTH" Controls the indentation of the \s-1XML\s0 tags in the final outputs. For example, you can temporarily disable a tag's indentation by the following lines of code: .Sp .Vb 6 \& body { \& pre { \& local $Template::Declare::Tags::TAG_NEST_DEPTH = 0; \& script { attr { src => \*(Aqfoo.js\*(Aq } } \& } \& } .Ve .Sp It generates .Sp .Vb 5 \& \&
\& 
\&  
\& .Ve .Sp Note that now the \f(CW\*(C`script\*(C'\fR tag has \fIno\fR indentation and we've got what we want. ;) .ie n .IP "$Template::Declare::Tags::SKIP_XML_ESCAPING" 4 .el .IP "\f(CW$Template::Declare::Tags::SKIP_XML_ESCAPING\fR" 4 .IX Item "$Template::Declare::Tags::SKIP_XML_ESCAPING" Disables \s-1XML\s0 escape postprocessing entirely. Use at your own risk. .SH "SEE ALSO" .IX Header "SEE ALSO" Template::Declare::TagSet::HTML, Template::Declare::TagSet::XUL, Template::Declare. .SH "AUTHORS" .IX Header "AUTHORS" Jesse Vincent .PP Agent Zhang .SH "COPYRIGHT" .IX Header "COPYRIGHT" Copyright 2006\-2009 Best Practical Solutions, \s-1LLC.\s0