Home

Search this site:
 

Horshack’s
very
own site

 

This is Bavaria, Germany!
You will find links to Perl,
bootdisks for system administration,
a lot of Linux,
Windows administration
and some personal belongings.
Perl - Template::Toolkit

Template::Toolkit

When you are starting to write something like "exchange QQQsomethingEEE with variable $something" then it's time to consider "use Template;". The official page is http://www.template-toolkit.org. This page is simply as a cheat-sheet for me and demonstrating the most simple things.

Replacing a few simple variables

Variables and all template-toolkit-code is embedded in [% code or variable %]

use strict;
use warnings;
use Template;

my $input = <<'EOINPUT';
The title is [% title %] and it costs [% price %]
EOINPUT

my $vars = {
    title => 'Haegar, the Horrible',
    price => '5,60 Euros',
};

my $tt = Template->new();
my $output;

# \$input -> not a filename, template is in this stringvariable
# \$output means output to that variable
$tt->process( \$input, $vars, \$output )
  || die $tt->error;
printf "The result is:\n***%s***\n", $output;

# this would be output to a file:
# $tt->process( \$input, $vars, "output.txt" );

# this would be input from a file and output to a file:
# $tt->process( "templatefile.txt", $vars, "output.txt" );

Loops in Template Toolkit

You can also iterate over Arrays, ask for conditions and so on. There is [% FOR single IN array %] ... [% END %]
use strict;
use warnings;
use Template;

my $vars = {
    list_from => "December 2005",
    books => [
        {   
            title => 'Haegar, the Horrible',
            price => '5,60 Euros',
        },
        {   
            title => 'The Peanuts',
            price => '2,90 Euros',
        },
    ],
    shoplocations => [ 'Nuremberg', 'Berlin' ],
};

my $input = <<'EOINPUT';
Bookshelf from [% list_from %]

[% # minus-percent means: no linebreaks at this place -%]
[%- # percent-minus means: no linebreaks at this place -%]

[% FOREACH abook IN books -%]
-> [% abook.title %], for [% abook.price %]
[% END %]

Our shops are located in:
[% # a comment in the template %]
[% FOREACH alocation IN shoplocations -%]
* [%- alocation %]
[% END %]
EOINPUT


my $tt = Template->new();
my $output;

# \$input -> not a filename, template is in this stringvariable
# \$output means output to that variable
$tt->process( \$input, $vars, \$output )
  || die $tt->error;
printf "The result is:\n***\n%s\n***\n", $output;
The result is:
Bookshelf from December 2005

-> Haegar, the Horrible, for 5,60 Euros
-> The Peanuts, for 2,90 Euros

Our shops are located in:

* Nuremberg
* Berlin

Creating boring config-files

Life can be sooooo boring. I had to insert a lot of lines in config-files telling it tablespaces of oracle-databases. Template Toolkit is the right tool to create these configuration-snippets:
#!/usr/bin/perl
print <<EOUSE;
Create some boring configuration-lines...

EOUSE
use Template;

# These lines get repeated a lot of times
my $template2explode =<<'EOTEMPLATE';
# Server [% server %], Database [% database %]
[% FOREACH line IN list_of_things %]
define service{
    use                      generic-service
    host_name                oechsle.zdf
    check_period             serverzeit
    service_description      ORA_[% line.dbname | upper %]_[% line.tablespace | upper %]
    check_command            check_ora_tablespace!80!90![% line.dbname %]![% line.tablespace %]
}
[% END %]

EOTEMPLATE

# Variables to input into the template
my $dbname = "okf";
my @tablespaces = qw/
RBS
SYSTEM
TEMP
TSP_OKF_DAT01
TSP_OKF_IND01
/;


foreach my $tsp ( sort @tablespaces ) {
    push @list, {
            dbname => $dbname,
            tablespace => $tsp,
    }
}
my $vars = {
    database => $dbname,
    server => "oechsle.zdf",
    list_of_things => \@list,
};
my $output;

my $tt = Template->new;
$tt->process( \$template2explode, $vars, $output) || die $tt->error;
print $output;
The output of the program is this:
Create some boring configuration-lines...

# Server oechsle.zdf, Database okf

define service{
    use                      generic-service
    host_name                oechsle.zdf
    check_period             serverzeit
    service_description      ORA_OKF_RBS
    check_command            check_ora_tablespace!80!90!okf!RBS
}

define service{
    use                      generic-service
    host_name                oechsle.zdf
    check_period             serverzeit
    service_description      ORA_OKF_SYSTEM
    check_command            check_ora_tablespace!80!90!okf!SYSTEM
}

define service{
    use                      generic-service
    host_name                oechsle.zdf
    check_period             serverzeit
    service_description      ORA_OKF_TEMP
    check_command            check_ora_tablespace!80!90!okf!TEMP
}

define service{
    use                      generic-service
    host_name                oechsle.zdf
    check_period             serverzeit
    service_description      ORA_OKF_TSP_OKF_DAT01
    check_command            check_ora_tablespace!80!90!okf!TSP_OKF_DAT01
}

define service{
    use                      generic-service
    host_name                oechsle.zdf
    check_period             serverzeit
    service_description      ORA_OKF_TSP_OKF_IND01
    check_command            check_ora_tablespace!80!90!okf!TSP_OKF_IND01
}

Variable templates, take special not default

You want to create a letter with default parts, but want to use special parts for some special customers. The template letter.tt looks like this:

 [%# a comment, file: letter.tt %]
 Dear [% name %],

 we were pleased to meet you.

 [% INCLUDE gift.tt %]
 

The file-structure looks like this:

 tt/
    default/
        letter.tt       <-- INCLUDE gift.tt
        gift.tt
    lippmann/
        gift.tt
 

So customer lippmann gets HIS gift.tt, every other one gets the DEFAULT gift.tt

#!/usr/bin/perl
use strict;
use warnings;
use Template;

# Vars to get used by Template-Toolkit
my $vars = {
    # there is a template-directory with the customer's name
    # to implement special textparts if wanted
    customer => 'lippmann',
    # usual variables
    name => 'Mr. Lippmann',
};
  
my $tt_behaviour = {
    # first directory where file is found wins
    INCLUDE_PATH => [
        'tt/' . $vars->{customer},    # _special_ directory for customer
        'tt/default',                 # _default_ directory for customer
    ],
};  
my $tt = Template->new($tt_behaviour);
my $output;
$tt->process( "letter.tt", $vars, \$output )
  || die $tt->error;
print <<"EOTEXT";
The result is:
===
$output
===
EOTEXT

Special variables

Impressum