Template::Declare::Tags.3pm

Langue: en

Autres versions - même langue

Version: 2009-02-05 (debian - 07/07/09)

Section: 3 (Bibliothèques de fonctions)

NAME

Template::Declare::Tags - Build and install XML Tag subroutines for Template::Declare

SYNOPSIS

     package MyApp::Templates;
 
     use base 'Template::Declare';
     use Template::Declare::Tags 'HTML';
 
     template main => sub {
         link {}
         table {
             row {
                 cell { "Hello, world!" }
             }
         }
         img { attr { src => 'cat.gif' } }
         img { src is 'dog.gif' }
     };
 
     # Produces:
     # <link />
     # <table>
     #  <tr>
     #   <td>Hello, world!</td>
     #  </tr>
     # </table>
     # <img src="cat.gif" />
     # <img src="dog.gif" />
 
     package MyApp::Templates;
 
     use base 'Template::Declare';
     use Template::Declare::Tags
         'XUL', HTML => { namespace => 'html' };
 
     template main => sub {
         groupbox {
             caption { attr { label => 'Colors' } }
             html::div { html::p { 'howdy!' } }
             html::br {}
         }
     };
 
     # Produces:
     #   <groupbox>
     #    <caption label="Colors" />
     #    <html:div>
     #     <html:p>howdy!</html:p>
     #    </html:div>
     #    <html:br></html:br>
     #   </groupbox>
 
 

DESCRIPTION

"Template::Declare::Tags" is used to generate and install subroutines for tags into the user's namespace.

You can specify the tag sets used by providing a list of module list in the "use" statement:

     use Template::Declare::Tags qw/ HTML XUL /;
 
 

By default, it uses the tag set provided by Template::Declare::TagSet::HTML. So

     use Template::Declare::Tags;
 
 

is equivalent to

     use Template::Declare::Tags 'HTML';
 
 

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.

You can certainly specify your own tag set classes, as long as they subclass Template::Declare::TagSet and implement the corresponding methods (e.g. "get_tag_list").

If you implement a custom tag set module named "Template::Declare::TagSet::Foo".

  use Template::Declare::Tags 'Foo';
 
 

If you give the your tag set module a different name, say, "MyTag::Foo", then you use the "from" option:

  use Template::Declare::Tags Foo => { from => 'MyTag::Foo' };
 
 

Then "Template::Declare::Tags" will no longer try to load "Template::Declare::TagSet::Foo" and "MyTag::Foo" will be loaded instead.

XML namespaces are emulated by Perl packages. For example, you can embed HTML tags within XUL using the "html" namespace:

     package MyApp::Templates;
 
     use base 'Template::Declare';
     use Template::Declare::Tags
         'XUL', HTML => { namespace => 'html' };
 
     template main => sub {
         groupbox {
             caption { attr { label => 'Colors' } }
             html::div { html::p { 'howdy!' } }
             html::br {}
         }
     };
 
 

This will give you

        <groupbox>
         <caption label="Colors" />
         <html:div>
          <html:p>howdy!</html:p>
         </html:div>
         <html:br></html:br>
        </groupbox>
 
 

Behind the scene, "Template::Declare::Tags" will generate a Perl package named "html" and install HTML tag subroutines into that package. On the other hand, XUL tag subroutines are installed into the current package, namely, "MyApp::Templates" in the previous example.

There are cases when you want to specify a different Perl package for a perticular XML namespace name. For instance, the "html" 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, then the "package" option can come to rescue:

     package MyApp::Templates;
     use base 'Template::Declare';
     use Template::Declare::Tags
         'XUL', HTML => {
             namespace => 'htm',
             package => 'MyHtml'
         };
 
     template main => sub {
         groupbox {
             caption { attr { label => 'Colors' } }
             MyHtml::div { MyHtml::p { 'howdy!' } }
             MyHtml::br {}
         }
     };
 
 

This code snippet will still generate something like the following:

     <groupbox>
      <caption label="Colors" />
      <htm:div>
       <htm:p>howdy!</htm:p>
      </htm:div>
      <htm:br></htm:br>
     </groupbox>
 
 

METHODS AND SUBROUTINES

template TEMPLATENAME => sub { 'Implementation' };

"template" declares a template in the current package. You can pass any url-legal characters in the template name. "Template::Declare" will encode the template as a perl subroutine and stash it to be called with "show()".

(Did you know that you can have characters like ``:'' and ``/'' in your Perl subroutine names? The easy way to get at them is with ``can'').

create_wrapper WRAPPERNAME => sub { 'Implementation' };

"create_wrapper" 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 HTML headers and footers, you can do something like this:
   package MyApp::Templates;
   use Template::Declare::Tags;
   use base 'Template::Declare';
 
   BEGIN {
       create_wrapper wrap => sub {
           my $code = shift;
           my %params = @_;
           html {
               head { title { outs "Hello, $params{user}!"} };
               body {
                   $code->();
                   div { outs 'This is the end, my friend' };
               };
           }
       };
   }
 
   template inner => sub {
       wrap {
           h1 { outs "Hello, Jesse, s'up?" };
       } user => 'Jesse';
   };
 
 

Note how the "wrap" wrapper function is available for calling after it has been declared in a "BEGIN" block. Also note how you can pass arguments to the function after the closing brace (you don't need a comma there!).

The output from the ``inner'' template will look something like this:

   <html>
    <head>
     <title>Hello, Jesse!</title>
    </head>
    <body>
     <h1>Hello, Jesse, s&#39;up?</h1>
     <div>This is the end, my friend</div>
    </body>
   </html>
 
 

private template TEMPLATENAME => sub { 'Implementation' };

"private" declares that a template isn't available to be called directly from client code.

attr HASH

With "attr", you can specify attributes for HTML tags.

Example:

  p {
     attr { class => 'greeting text',
            id    => 'welcome' };
     'This is a welcoming paragraph';
  }
 
 

Tag attributes can also be specified by using "is", as in

  p {
     class is 'greeting text';
     id    is 'welcome';
     'This is a welcoming paragraph';
  }
 
 

xml_decl HASH

Emits XML declarators.

For example,

     xml_decl { 'xml', version => '1.0' };
     xml_decl { 'xml-stylesheet',  href => "chrome://global/skin/", type => "text/css" };
 
 

will produce

     <?xml version="1.0"?>
     <?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
 
 

outs STUFF

"outs" HTML-encodes its arguments and appends them to "Template::Declare"'s output buffer.

outs_raw STUFF

"outs_raw" appends its arguments to "Template::Declare"'s output buffer without doing any HTML escaping.

get_current_attr

Help! I'm deprecated/

install_tag TAGNAME, TAGSET

Sets up TAGNAME as a tag that can be used in user templates. TAGSET is an instance of a subclass for Template::Declare::TagSet.

with

"with" is an alternative way to specify attributes for a tag:
     with ( id => 'greeting', class => 'foo' ),
         p { 'Hello, World wide web' };
 
 

The standard way to do this is:

     p { attr { id => 'greeting', class => 'foo' }
         'Hello, World wide web' };
 
 

smart_tag_wrapper

   # create a tag that has access to the arguments set with with.
   sub sample_smart_tag (&) {
       my $code = shift;
 
       smart_tag_wrapper {
           my %args = @_; # set using 'with'
           outs( 'keys: ' . join( ', ', sort keys %args) . "\n" );
           $code->();
       };
   }
 
   # use it
   with ( foo => 'bar', baz => 'bundy' ),
     sample_smart_tag {
       outs( "Hello, World!\n" );
     };
 
   # output would be
   keys: baz, foo
   Hello, World!
 
 

The smart tag wrapper allows you to create code that has access to the arguments set using 'with', it passes them in to the wrapped code in @_. It also takes care of putting the output in the right place and tidying up after itself.

show [$template_name or $template_coderef], args

"show" displays templates. "args" will be passed directly to the template.

"show" can either be called with a template name or a package/object and a template. (It's both functional and OO.)

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 wil be visible.

From the outside world, users can either call "Template::Declare-"show()> or "Template::Declare::tags::show()" to render a publicly visible template.

``private'' templates may only be called from within the "Template::Declare" package.

current_template

Returns the absolute path of the current template

import 'Package' under 'path'

Import the templates from "Package" into the subpath 'path' of the current package, clobbering any of your own package's templates that you'd already defined.

under

"under" is a helper function for the ``import'' semantic sugar.

VARIABLES

@Template::Declare::Tags::EXPORT
Holds the names of the static subroutines exported by this class. tag subroutines generated from certain tag set, however, are not included here.
@Template::Declare::Tags::TAG_SUB_LIST
Contains the names of the tag subroutines generated from certain tag set.

Note that this array won't get cleared automatically before a another "use Template::Decalre::Tags" statement.

@Template::Declare::Tags::TagSubs is aliased to this variable for backward-compatibility.

$Template::Declare::Tags::TAG_NEST_DEPTH
Controls the indentation of the XML tags in the final outputs. For example, you can temporarily disable a tag's indentation by the following lines of code:
     body {
         pre {
           local $Template::Declare::Tags::TAG_NEST_DEPTH = 0;
           script { attr { src => 'foo.js' } }
         }
     }
 
 

It generates

     <body>
      <pre>
     <script src="foo.js"></script>
      </pre>
     </body>
 
 

Note that now the "script" tag has no indentation and we've got what we want ;)

$Template::Declare::Tags::SKIP_XML_ESCAPING
Makes Template::Declare skip the XML escaping postprocessing entirely.

SEE ALSO

Template::Declare::TagSet::HTML, Template::Declare::TagSet::XUL, Template::Declare.

AUTHOR

Jesse Vincent <jesse@bestpractical.com>, Agent Zhang <agentzh@yahoo.cn> Copyright 2006-2007 Best Practical Solutions, LLC