Uri Guttman > Template-Simple > Template::Simple

Download:
Template-Simple-0.04.tar.gz

Dependencies

Annotate this POD (1)

CPAN RT

New  3
Open  0
View/Report Bugs
Module Version: 0.04   Source   Latest Release: Template-Simple-0.06

NAME ^

Template::Simple - A simple and very fast template module

VERSION ^

Version 0.03

SYNOPSIS ^

    use Template::Simple;

    my $tmpl = Template::Simple->new();

  # here is a simple template store in a scalar
  # the header and footer templates will be included from the cache or files.

    my $template_text = <<TMPL ;
[%INCLUDE header%]
[%START row%]
        [%first%] - [%second%]
[%END row%]
[%INCLUDE footer%]
TMPL

  # this is data that will be used to render that template the keys
  # are mapped to the chunk names (START & END markups) in the
  # template the row is an array reference so multiple rows will be
  # rendered usually the data tree is generated by code instead of
  # being pure data.

    my $data = {
        header  => {
                date    => 'Jan 1, 2008',
                author  => 'Me, myself and I',
        },
        row     => [
                {
                        first   => 'row 1 value 1',
                        second  => 'row 1 value 2',
                },
                {
                        first   => 'row 2 value 1',
                        second  => 'row 2 value 2',
                },
        ],
        footer  => {
                modified        => 'Aug 31, 2006',
        },
    } ;

  # this call renders the template with the data tree

    my $rendered = $tmpl->render( \$template_text, $data ) ;

  # here we add the template to the cache and give it a name

    $tmpl->add_template( demo => $template_text ) ;

  # this compiles and then renders that template with the same data
  # but is much faster

    $tmpl->compile( 'demo' ) ;
    my $rendered = $tmpl->render( 'demo', $data ) ;

DESCRIPTION ^

Template::Simple is a very fast template rendering module with a simple markup. It can do almost any templating task and is extendable with user callbacks. It can render templates directly or compile them for more speed.

CONSTRUCTOR ^

new

You create a Template::Simple by calling the class method new:

        my $tmpl = Template::Simple->new() ;

All the arguments to new() are key/value options that change how the object will render templates.

pre_delim

This option sets the string or regex that is the starting delimiter for all markups. You can use a plain string or a qr// but you need to escape (with \Q or \) any regex metachars if you want them to be plain chars. The default is qr/\[%/.

        my $tmpl = Template::Simple->new(
                pre_delim => '<%',
        );

        my $rendered = $tmpl->render( '<%FOO%]', 'bar' ) ;

post_delim

This option sets the string or regex that is the ending delimiter for all markups. You can use a plain string or a qr// but you need to escape (with \Q or \) any regex metachars if you want them to be plain chars. The default is qr/%]/.

        my $tmpl = Template::Simple->new(
                post_delim => '%>',
        );

        my $rendered = $tmpl->render( '[%FOO%>', 'bar' ) ;

greedy_chunk

This boolean option will cause the regex that grabs a chunk of text between the START/END markups to become greedy (.+). The default is a not-greedy grab of the chunk text. (UNTESTED)

templates

This option lets you load templates directly into the cache of the Template::Simple object. See <TEMPLATE CACHE> for more on this.

        my $tmpl = Template::Simple->new(
                templates       => {
                        foo     => <<FOO,
[%baz%] is a [%quux%]
FOO
                        bar     => <<BAR,
[%user%] is not a [%fool%]
BAR
                },
        );

search_dirs, include_paths

This option lets you set the directory paths to search for template files. Its value is an array reference with the paths. Its default is 'templates'.

        my $tmpl = Template::Simple->new(
                        search_dirs => [ qw(
                                templates
                                templates/deeper
                        ) ],
        ) ;

NOTE: This option was called include_paths but since it is used to locate named templates as well as included ones, it was changed to search_dirs. The older name include_paths is still supported but new code should use search_dirs.

METHODS ^

render

This method is passed a template and a data tree and it renders it and returns a reference to the resulting string.

If the template argument is a scalar reference, then it is the template text to be rendered. A scalar template argument is first assumed to be a template name which is searched for in the template cache and the compiled template caches. If found in there it is used as the template. If not found there, it is searched for in the directories of the include_paths. Finally if not found, it will be used as the template text.

The data tree argument can be any value allowed by Template::Simple when rendering a template. It can also be a blessed reference (Perl object) since Scalar::Util::reftype is used instead of ref to determine the data type.

Note that the author recommends against passing in an object as this breaks encapsulation and forces your object to be (most likely) a hash. It would be better to create a simple method that copies the object contents to a hash reference and pass that. But other current templaters allow passing in objects so that is supported here as well.

    my $rendered = $tmpl->render( $template, $data ) ;

compile

This method takes a template and compiles it to make it run much faster. Its only argument is a template name and that is used to locate the template in the object cache or it is loaded from a file (with the same search technique as regular rendering). The compiled template is stored in its own cache and can be rendered by a call to the render method and passing the name and the data tree.

    $tmpl->compile( 'foo' ) ;
    my $rendered = $tmpl->render( 'foo', $data ) ;

There are a couple of restrictions to compiled templates. They don't support code references in the data tree (that may get supported in the future). Also since the include expansion happens one time during the compiling, any changes to the template or its includes will not be detected when rendering a compiled template. You need to re-compile a template to force it to use changed templates. Note that you may need to delete templates from the object cache (with the delete_templates method) to force them to be reloaded from files.

add_templates

This method adds templates to the object cache. It takes a list of template names and texts just like the templates constructor option. These templates are located by name when compiling or rendering.

        $tmpl->add_templates( 
                {
                        foo     => \$foo_template,
                        bar     => '[%include bar%]',
                }
        ) ;

delete_templates

This method takes a list of template names and will delete them from the template cache in the object. If you pass no arguments then all the cached templates will be deleted. This can be used when you know a template file has been updated and you want to get it loaded back into the cache.

    # this deletes only the foo and bar templates from the object cache

        $tmpl->delete_templates( qw( foo bar ) ;

    # this deletes all of templates from the object cache

        $tmpl->delete_templates() ;

get_source

        $tmpl->get_source( 'bar' ) ;

This method is passed a compiled template name and returns the generated Perl source for a compiled template. You can compile a template and paste the generated source (a single sub per template) into another program. The sub can be called and passed a data tree and return a rendered template. It saves the compile time for that template but it still needs to be compiled by Perl. This method is also useful for debugging the template compiler.

TEMPLATE CACHE ^

This cache is stored in the object and will be searched to find any template by name. It is initially loaded via the templates option to new and more can be added with the add_templates method. You can delete templates from the cache with the delete_templates method. Compiled templates have their own cache in the module. Deleting a template also deletes it from the compiled cache.

INCLUDE EXPANSION ^

Before a template is either rendered or compiled it undergoes include expansion. All include markups are replaced by a templated located in the cache or from a file. Included templates can include other templates. This expansion keeps going until no more includes are found.

LOCATING TEMPLATES ^

When a template needs to be loaded by name (when rendering, compiling or expanding includes) it is first searched for in the object cache (and the compiled cache for compiled templates). If not found there, the templates_paths are searched for files with that name and a suffix of .tmpl. If a file is found, it used and also loaded into the template cache in the object with the searched for name as its key.

MARKUP ^

All the markups in Template::Simple use the same delimiters which are [% and %]. You can change the delimiters with the pre_delim and post_delim options in the new() constructor.

Tokens

A token is a single markup with a \w+ Perl word inside. The token can have optional whitespace before and after it. A token is replaced by a value looked up in a hash with the token as the key. The hash lookup keeps the same case as parsed from the token markup.

    [% foo %] [%BAR%]

Those will be replaced by $href-{foo}> and $href-{BAR}> assuming $href is the current data for this rendering. Tokens are only parsed out during hash data rendering so see Hash Data for more.

Chunks

Chunks are regions of text in a template that are marked off with a start and end markers with the same name. A chunk start marker is [%START name%] and the end marker for that chunk is [%END name%]. name is a \w+ Perl word which is the name of this chunk. The whitespace between START/END and name is required and there is optional whitespace before START/END and after the name. START/END are case insensitive but the name's case is kept. Chunks are the primary way to markup templates for structures (sets of tokens), nesting (hashes of hashes), repeats (array references) and callbacks to user code. By default a chunk will be a non-greedy grab but you can change that in the constructor by enabling the greedy_chunk option.

    [%Start FOO%]
        [% START bar %]
                [% field %]
        [% end bar %]
    [%End FOO%]

Includes

When a markup [%include bar%] is seen, that text is replaced by the template of that name. See INCLUDE EXPANSION for more on this. =head2 Include Rendering

RENDERING RULES ^

Template::Simple has a short list of rendering rules and they are easy to understand. There are two types of renderings, include rendering and chunk rendering. In the render method, the template is an unnamed top level chunk of text and it first gets its INCLUDE markups rendered. The text then undergoes a chunk rendering and a scalar reference to that rendered template is returned to the caller.

Chunk Rendering

A chunk is the text found between matching START and END markups and it gets its name from the START markup. The top level template is considered an unamed chunk and also gets chunk rendered.

The data for a chunk determines how it will be rendered. The data can be a scalar or scalar reference or an array, hash or code reference. Since chunks can contain nested chunks, rendering will recurse down the data tree as it renders the chunks. Each of these renderings are explained below. Also see the IDIOMS and BEST PRACTICES section for examples and used of these renderings.

Hash Data Rendering

If the current data for a chunk is a hash reference then two phases of rendering happen, nested chunk rendering and token rendering. First nested chunks are parsed of of this chunk along with their names. Each parsed out chunk is rendered based on the value in the current hash with the nested chunk's name as the key.

If a value is not found (undefined), then the nested chunk is replaced by the empty string. Otherwise the nested chunk is rendered according to the type of its data (see chunk rendering) and it is replaced by the rendered text.

Chunk name and token lookup in the hash data is case sensitive.

Note that to keep a plain text chunk or to just have the all of its markups (chunks and tokens) be deleted just pass in an empty hash reference {} as the data for the chunk. It will be rendered but all markups will be replaced by the empty string.

The second phase is token rendering. Markups of the form [%token%] are replaced by the value of the hash element with the token as the key. If a token's value is not defined it is replaced by the empty string. This means if a token key is missing in the hash or its value is undefined or its value is the empty string, the [%token%] markup will be deleted in the rendering.

Array Data Rendering

If the current data for a chunk is an array reference it will do a full chunk rendering for each value in the array. It will replace the original chunk text with the concatenated list of rendered chunks. This is how you do repeated sections in Template::Simple and why there is no need for any loop markups. Note that this means that rendering a chunk with $data and [ $data ] will do the exact same thing. A value of an empty array [] will cause the chunk to be replaced by the empty string.

Scalar Data Rendering

If the current data for a chunk is a scalar or scalar reference, the entire chunk is replaced by the scalar's value. This can be used to overwrite one default section of text with from the data tree.

Code Data Rendering

If the current data for a chunk is a code reference (also called anonymous sub) then the code reference is called and it is passed a scalar reference to the that chunk's text. The code must return a scalar or a scalar reference and its value replaces the chunk's text in the template. If the code returns any other type of data it is a fatal error. Code rendering is how you can do custom renderings and plugins. A key idiom is to use closures as the data in code renderings and keep the required outside data in the closure.

DESIGN GOALS ^

BUGS ^

Please report any bugs or feature requests to bug-template-simple at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Template-Simple. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

ACKNOWLEDGEMENTS ^

I wish to thank Turbo10 for their support in developing this module.

LICENSE

  Same as Perl.

COPYRIGHT ^

Copyright 2011 Uri Guttman, all rights reserved.

SEE ALSO

An article on file slurping in extras/slurp_article.pod. There is also a benchmarking script in extras/slurp_bench.pl.

AUTHOR ^

Uri Guttman, <uri@stemsystems.com>

syntax highlighting: