[DEPRECATED] Multi purpose template engine
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
lib/Text
t
xt
.gitignore
Changes
MANIFEST
MANIFEST.SKIP
MANIFEST.bak
Makefile.PL
README.pod

README.pod

NAME

Text::PSTemplate - Multi purpose template engine

SYNOPSIS

use Text::PSTemplate;

$template = Text::PSTemplate->new;

$template->set_var(key1 => $value1, key2 => $value2);
$template->set_func(key1 => \&func1, key2 => \&func2);

$str = $template->parse($str);
$str = $template->parse_str($str);
$str = $template->parse_str($file_obj);
$str = $template->parse_file($filename);
$str = $template->parse_file($file_obj);
$str = $template->parse_block($index);

DESCRIPTION

Text::PSTemplate is a multi purpose template engine. This module allows you to include variables and function calls into your templates.

Essential syntax

The essential syntax for writing template is as follows.

Special tagging
<% ... %>
Perl style variable and function calls
<% $some_var %>
<% some_func(...) %>
Line breaks in tags
<%
    product_list(
        limit       => 20,
        category    => 'books',
    )
%>
Block syntax
<% your_func()<<EOF,EOF2 %>
    inline data
<% EOF %>
    inline data2
<% EOF2 %>
escaping

tag delimiter can be escaped by backslashes so that the delimiter characters themselves appear to the output. If you want to parse the statement after backslash, you can double escape.

\<% this appears literally %>   ### literally
\\<% $var %>                    ### A backlash and parsed value
\\\<% this appears literally %> ### A backslash and literal
\\\\<% $var %>                  ### Two backlashes and parsed value
....

Character $ and & is interpolated in any part of statements even in single quotes. So you must escape them with backslashes when it's needed.

<% some_func(price => '\$10.25') %>

Plugin

This template engine provides a plugin mechanism. A plugin can define functions for templates.

A plugin must inherits Text::PSTemplate::PluginBase. Once inherit it, the plugin class get capable of TplExport attribute.

package MyPlug;
use base qw(Text::PSTemplate::PluginBase);

sub say_hello_to : TplExport {
    my ($self, $name) = (@_);
    return "Hello $name";
}

You can activate it as follows.

$template->plug('MyPlug');

# or with namespace

$template->plug('MyPlug','My::Name::Space');

The function is available as follows.

<% say_hello_to('Nick') %>

Core plugins

Text::PSTemplate automatically activate some core plugins.

Core plugins
Control
Env
Extends
Util
FS

Text::PSTemplate::Plugin::Control plugin

<% if_equals($some_var, 'a')<<THEN,ELSE %>
    then
<% THEN %>
    else
<% ELSE %>

<% if($some_var)<<THEN,ELSE %>
    true
<% THEN %>
    not true
<% ELSE %>

<% if_in_array($some_var, ['a','b','c'])<<THEN,ELSE %>
    found
<% THEN %>
    not found
<% ELSE %>

<% switch($some_var, ['a', 'b'])<<CASE1,CASE2,DEFAULT %>
    match a
<% CASE1 %>
    match b
<% CASE2 %>
    default
<% DEFAULT %>

<% tpl_switch($some_var, {
    a => 'path/to/tpl_a.txt',
    b => 'path/to/tpl_b.txt',
}, 'path/to/tpl_default.txt') %>

<% substr($some_var, 0, 2, '...') %>

<% each($array_ref, 'name')<<TPL %>
    This is <%$name%>.
<% TPL %>

<% each($array_ref, 'index' => 'name')<<TPL %>
    No.<%$index%> is <%$name%>.
<% TPL %>

<% each($hash_ref, 'name')<<TPL %>
    This is <%$name%>.
<% TPL %>

<% each($has_href, 'key' => 'name')<<TPL %>
    Key '<%$key%>' contains <%$name%>.
<% TPL %>

<% include('path/to/file.txt', {some_var => 'aaa'}) %>

<% default($var, $default) %>

Text::PSTemplate::Plugin::Extends plugin

base.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <link rel="stylesheet" href="style.css" />
    <title><% placeholder('title')<<DEFAULT %>My amazing site<% DEFAULT %></title>
</head>

<body>
    <div id="sidebar">
        <% placeholder('sidebar')<<DEFAULT %>
        <ul>
            <li><a href="/">Home</a></li>
            <li><a href="/blog/">Blog</a></li>
        </ul>
        <% DEFAULT %>
    </div>

    <div id="content">
        <% placeholder('content')<<DEFAULT %><% DEFAULT %>
    </div>
</body>
</html>

child.html

<% extends('base.html')<<EXTENDS %>
    <% block('title')<<BLOCK %>My amazing blog<% BLOCK %>
    <% block('content')<<BLOCK %><% each($blog_entries, 'entry')<<ENTRIES %>
        <h2><% $entry->{title} %></h2>
        <p><% $entry->{body} %></p>
    <% ENTRIES %><% BLOCK %>
<% EXTENDS %>

Text::PSTemplate::Plugin::Util plugin

<% commify($num) %>

<% substr($var, $start, $length, $alterative) %>
<% substr($some_var, 0, 2, '...') %>

<% counter(start=10, skip=5) %>
<% counter() %>
<% counter() %>
<% counter(start=10, direction=down) %>
<% counter() %>

METHODS

Text::PSTemplate->new($mother)

Constructor. This method can take an argument $mother which should be a Text::PSTemplate instance. Most member attributes will be inherited from their mother at referring phase. So you don't have to set all settings again and again. Just tell a mother to the constructor. If this constructor is called from a template function, meaning the instantiation is recursive, this constructor auto detects the nearest mother to be set to new instance's mother.

If you want really new instance, give an undef to constructor explicitly.

Text::PSTemplate->new(undef)

Text::PSTemplate::get_current_parser()

This can be called from template functions. If current context is recursed instance, this returns mother instance.

$parser = Text::PSTemplate::get_current_parser;

Text::PSTemplate::get_current_file_parser()

This can be called from template functions. This returns file-contextual mother template instance.

$parser = Text::PSTemplate::get_current_file_parser;

Text::PSTemplate::get_current_filename()

This can be called from template functions. If current context is originated from a file, this returns the file name.

$instance->set_filter($key, $filter_code_ref)

Add a filter for given key in code ref.

my $tpl = Text::PSTemplate->new;
$tpl->set_filter('[escape]', \&escape);

# in templates..

<%[escape] $val %>

Text::PSTemplate::set_chop($mode)

This method set the behavior of the parser how they should treat follow up line breaks. If argument $mode is 1, line breaks will not to be output. 0 is default.

Text::PSTemplate::get_block($index, $options)

This can be called from template functions. This Returns block data specified in templates.

In a template

<% your_func()<<EOF1,EOF2 %>
foo
<% EOF1 %>
bar
<% EOF2 %>

Function definition

sub your_func {
    my $block1 = Text::PSTemplate::get_block(0) # foo with newline chara
    my $block2 = Text::PSTemplate::get_block(1) # bar with newline chara
    my $block1 = Text::PSTemplate::get_block(0, {chop_left => 1}) # foo
    my $block2 = Text::PSTemplate::get_block(1, {chop_right => 1}) # bar
}

$instance->set_encoding($encode or $encode_array_ref)

This setting will be thrown at file open method. Default is 'utf8'.

$instance->set_encoding('cp932')

You can set a array reference for guessing encoding. The value will be thrown at Encode::guess_encoding.

$instance->set_encoding(['euc-jp', 'shiftjis', '7bit-jis'])

$instance->set_exception($code_ref)

This is a callback setter. If any errors occurred at parsing phase, the $code_ref will be called. Your callback subroutine can get following arguments.

$template->set_exception(sub {
    my ($self, $line, $err) = (@_);
});

With these arguments, you can log the error, do nothing and return '', or reconstruct the tag and return it as if the tag was escaped. See also Text::PSTemplate::Exception Class for example.

$instance->set_var_exception($code_ref)

$instance->set_func_exception($code_ref)

$instance->set_recur_limit($number)

This class instance can recursively have a mother instance as an attribute. This setting limits the recursion at given number. The default is 10.

$template->set_recur_limit(10);

$instance->get_param($name)

$instance->set_delimiter($left, $right)

Set delimiters.

$instance->set_delimiter('<!-- ', ' -->')

$instance->get_delimiter(0 or 1)

Get delimiters

$instance->get_delimiter(0) # left delimiter
$instance->get_delimiter(1) # right delimiter

$instance->set_var(%datasets)

This method Sets variables which can be referred from templates.

$instance->set_var(a => 'b', c => 'd')

This can take null string too. You can't set undef for value.

$instance->var($name)

Get template variables

$instance->var('a')

$instance->set_func(some_name => $code_ref)

Set template functions

$a = sub {
    return 'Hello '. $_[0];
};
$instance->set_func(say_hello_to => $a)

Inside template...
<% say_hello_to('Fujitsu san') %>

$instance->func(name)

Get template functions. This method is aimed at internal use.

$instance->parse($str)

This method parses templates given in string.

$tpl->parse('...')

$instance->parse_str($str)

$instance->parse_str($file_obj)

This method parses templates given in string or Text::PSTemplate::File instance.

$tpl->parse_str('...')
$tpl->parse_str($obj)

$instance->parse_file($file_path)

$instance->parse_file($file_obj)

This method parses templates given in filename or Text::PSTemplate::File instance.

$tpl->parse_file($file_path)
$tpl->parse_file($obj)

$instance->parse_block($index, $args)

$tpl->parse_block(0, {chop_left => 1})

$instance->get_file($name, $trans_ref)

This returns a Text::PSTemplate::File instance of given file name which contains file name and file content together. If $trans_ref is set or $instance already has a translation code in its attribute, the file name is translated with the code. You can set undef for $trans_ref then both options are bypassed.

$instance->set_filename_trans_coderef($code_ref)

This method sets a callback subroutine which defines a translating rule for file name.

This example sets the base template directory.

$tpl->set_filename_trans_coderef(sub {
    my $name = shift;
    return '/path/to/template/base/directory'. $name;
});

This example allows common extension to be omitted.

$trans = sub {
    my $name = shift;
    if ($name !~ /\./) {
        return $name . '.html'
    }
    return $name;
}
$tpl->set_filename_trans_coderef($trans)

This also let you set a default template in case the template not found.

Text::PSTemplate::dump($object)

Debug

$instance->plug($package, $namespace)

This method activates a plugin into your template instance.

$instance->plug('Path::To::SomePlugin');

The functions will available as follows.

<% Path::To::SomePlugin::some_function(...) %>

You can load plugins into specific namespaces.

$instance->plug('Path::To::SomePlugin', 'MyNamespace');

This functions will available as follows

<% MyNamespace::some_function(...) %>

You can merge plugins into single namespace or even the root namespace which used by core plugins.

$instance->plug('Plugin1', 'MyNamespace');
$instance->plug('Plugin2', 'MyNamespace');
$instance->plug('Plugin1', '');

$instance->get_plugin($name)

This method returns the plugin instance for given name.

$instance->get_as($plug_id)

This method returns the namespace for the plugin. Since it's just to be called from PluginBase abstract class, you don't worry about it.

get_func_list

Output list of available template function in text format.

AUTHOR

Sugama Keita, <sugama@jamadam.com>

COPYRIGHT AND LICENSE

Copyright (C) 2011 by Sugama Keita.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.