Thomas Wittek > Konstrukt > Konstrukt::Plugin::template

Download:
konstrukt/Konstrukt-0.5-beta13.tar.gz

Dependencies

Annotate this POD

CPAN RT

New  1
Open  0
View Bugs
Report a bug
Source  

NAME ^

Konstrukt::Plugin::template - Konstrukt templating engine

SYNOPSIS ^

Tag interface

        <& template src="some.template" &>
                <$ field $>will be inserted in the template<$ / $>
        <& / &>

Perl interface

        use_plugin 'template';
        $self->add_node($template->node('path/to/some.template', { 
                field1 => 'value1',
                some_list => [
                        { field1 => 'a', field2 => 'b' },
                        { field1 => 'c', field2 => 'd' },
                        ...
                ]
        }));

DESCRIPTION ^

An important goal of this framework is the fast creation of maintainable static content. Therefore the template (Konstrukt::Plugin::template) plugin was developed.

You are enouraged to encapsulate your web site components that are used in several places in templates, which then can be reused to avoid redundancy. A website usually consists of several components, that are used in many pages (layout, navigation, frames, tables, ...).

Each template consists of static text and variable parts, that can be substituted on the usage of the template.

There are two interfaces to this plugin. You may use special tags within your documents that will not annoy a non-programmer and fit seemlessly into the other markup. You may also use a perl-interface that will fit into your perl code (plugins or embedded perl).

Tag interface / Syntax

Fields

Templates can contain single variable fields, which can be substituted on the usage of the template and may have a default value.

Definition: some.template

        some text here
        this <+$ field_name $+>should be<+$ / $> replaced.
        some text there
        a field without a default value: <+$ no_default / $+>
        end

Usage:

        here we will use the template:
        <& template src="some.template" &>
                <$ field_name $>has been<$ / $>
                <$ no_default $>foo<$ / $>
        <& / &>
        
        you can also define the field values with a tag attribute:
        <& template src="some.template" no_default="bar" / &>

Result: (whitespaces may vary...)

        here we will use the template:
        
        some text here
        this has been replaced.
        some text there
        a field without a default value: foo
        end
        
        you can also define the field values with a tag attribute:
        
        some text here
        this should be replaced.
        some text there
        a field without a default value: bar
        end

Lists

You may define lists to generate repetitive content inside a template.

Definition: some.template

        <table>
                <tr><th><+$ head1 / $+></th><th><+$ head2 / $+></th></tr>
                <+@ items @+>
                <tr><td><+$ col1 / $+></td><td><+$ col2 / $+></td></tr>
                <+@ / @+>
        </table>

Usage:

        <& template src="some.template" head1="Name" head2="Telephone number" &>
                <@ items @>
                        <$ col1 $>foo<$ / $><$ col2 $>555-123456<$ / $>
                        <$ col1 $>bar<$ / $><$ col2 $>555-654321<$ / $>
                        <$ col1 $>baz<$ / $><$ col2 $>555-471123<$ / $>
                <@ / @>
        <& / &>

Result: (whitespaces may vary...)

        <table>
                <tr><th>Name</th><th>Telephone number</th></tr>
                <tr><td>foo</td><td>555-123456</td></tr>
                <tr><td>bar</td><td>555-654321</td></tr>
                <tr><td>baz</td><td>555-471123</td></tr>
        </table>

Note that lists of lists are currently not supported.

Special values:

Additionally to the explicitly specified values, you can access these additional values in each row:

Example:

        <table>
                <tr>
                        <th>ID</th>
                        <th>Name</th>
                </tr>
                <+@ items @+>
                <tr<& if condition="<+$ even / $+>" &> style="background-color: #8888FF;"<& / &>>
                        <th><+$ index / $+></th>
                        <th><+$ name / $+></th>
                </tr>
                <+@ / @+>
        </table>

Nested templates

Templates can be nested (as any Konstrukt tag):

        <& template src="layout.template" title="perl links" &>
                <$ content $>
                        Some perl links:
                        <& template src="linklist.template" &>
                                <@ links @>
                                        <$ target      $>http://www.cpan.org/<$ / $>
                                        <$ description $>Comprehensive Perl Archive Network<$ / $>
                                        
                                        <$ target      $>http://dev.perl.org/perl6/<$ / $>
                                        <$ description $>Perl 6 Development Page<$ / $>
                                        
                                        <$ target      $>http://www.perlfoundation.org/<$ / $>
                                        <$ description $>The Perl Foundation<$ / $>
                                <@ / @>
                        <& / &>
                <$ / $>
        <& / &>

Each used template can in turn contain template tags (and other special Konstrukt tags):

linklist.template:

        <ul>
        <+@ links @+>
                <li><a href="<+$ target / $+>"><+$ description $+>(No Description)<+$ / $+></a></li>
        <+@ / @+>
        <& template src="linkdisclaimer.template" / &>

The templates will be recursively processed.

Nested field definitions

You can also nest field definitions. So you can say that the default for one field is the value of another field:

        <+$ some_field $+><+$ default_for_some_field / $+><+$ / $+>

So if no value for some_field is defined, it will default to the value of default_for_some_field, which in turn could also have a default value and so on.

Perl interface

You may also use a template from your perl code. It will be inserted at the current position in the document where your perl code has been executed. This will be done with the "node" method:

        #get a plugin-object
        my $template = use_plugin 'template';
        
        #values that should be inserted to the template
        my $data = { 
                field1 => 'value1',
                field2 => 'value2'
                some_list => [
                        { field1 => 'a', field2 => 'b' },
                        { field1 => 'c', field2 => 'd' },
                        ...
                ]
        };
        #insert the template
        $self->add_node($template->node('path/to/some.template', $data));

You may also pass tag nodes as the field's content, so nested templates are possible:

        $self->add_node($template->node('some.template', { some_field => $template->node('some_other.template') }));

If you want to pass several nodes as the field's content, you must put them into a field node, which will act like a container:

        #create new field node as a container for some other nodes:
        my $container = Konstrukt::Parser::Node->new({ type => 'tag', handler_type => '$' });
        #add some nodes:
        $container->add_child($some_node);
        #...
        #create template node
        $self->add_node($template->node('some.template', { some_field => $container }));

Take a look at </node> (which has been used in the examples above), which explains the passing of template values a bit more.

CONFIGURATION ^

For some uncommon situations you may control the behaviour of this plugin with these settings:

        #this setting controls what to do when you have multiple <$ field $>-definitions:
        #0 = overwrite (default). only the last definition will be used
        #1 = join. join all values
        #2 = ignore. only the first definition will be used
        template/join_multiple_fields 0
        
        #this will allow the dynamic generation of <$ field $>'s like this:
        #<& template src="some.template" &>
        #       <$ static_field $>value<$ / $>
        #       <& perl &>print '<$ dynamic_field $>value<$ / $>'<& / &>
        #<& / &>
        #usally you shouldn't do this as it will slow down the execution.
        #if you want dynamic values, you should use the native perl-interface (L</node>) of this plugin.
        #FIXME: additionally this feature doesn't work correctly right now
        template/allow_dynamic_field_value_generation 0

SPEED ^

This plugin needs another modules to clone data structures. It will try to load them in this order:

        1) Clone
        2) Clone::Fast
        3) Scalar::Util::Clone
        4) Storable
        5) Clone::More
        6) Clone::PP

This precedence list is approximateley built to try the module with the best performance first. So you should check, if you've got any of the first modules installed.

METHODS ^

init

Initialization.

execute_again

Yes, this plugin may return dynamic nodes. E.g. by loading a template containing an perl node.

prepare

Prepare method

Parameters:

execute

Execute method

Parameters:

process

As prepare and execute are almost the same each run will just call this method.

Parameters:

check_preliminary_tags

Traverses the tree and looks for preliminary tags that now may have only plaintext children (as a <+$ variable / $+> might have been replaced by a plaintext node) and thus can be prepared.

Parameters:

scan_for_values

Traverses the tree and creates a handy data structure to easily access the values.

Parameters:

scan_for_templates

Traverses the tree (prepare-result of the block) and creates a handy data structure to easily access the templates.

Parameters:

substitute

Does the template substitution. It will do no parsing, it will just do the substitution on the passed trees.

Parameters:

set_hints

Traverses the tree and adds a reference to the field values to each plugin tag node inside the template (if not already set). Also adds a hint with the path of the current template, which will be used by the parser to track the correct current directory.

The values will then be accessible through $tag->{template_values} and $tag->{template_path}.

Parameters:

node

Return a tag node that will load a template. See "SYNOPSIS" for an example.

Parameters:

normalize_input_data

Will convert the input data, that may be passed in a short form, into the generic form.

Will only be used internally by "node".

Parameters:

AUTHOR ^

Copyright 2006 Thomas Wittek (mail at gedankenkonstrukt dot de). All rights reserved.

This document is free software. It is distributed under the same terms as Perl itself.

SEE ALSO ^

Konstrukt::Plugin, Konstrukt