Add built local::lib
[catagits/Gitalist.git] / local-lib5 / man / man3 / Template::Tutorial::Datafile.3pm
diff --git a/local-lib5/man/man3/Template::Tutorial::Datafile.3pm b/local-lib5/man/man3/Template::Tutorial::Datafile.3pm
new file mode 100644 (file)
index 0000000..363d037
--- /dev/null
@@ -0,0 +1,586 @@
+.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.3
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sh \" Subsection heading
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings.  \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote.  | will give a
+.\" real vertical bar.  \*(C+ will give a nicer C++.  Capital omega is used to
+.\" do unbreakable dashes and therefore won't be available.  \*(C` and \*(C'
+.\" expand to `' in nroff, nothing in troff, for use with C<>.
+.tr \(*W-|\(bv\*(Tr
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+.    ds -- \(*W-
+.    ds PI pi
+.    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+.    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch
+.    ds L" ""
+.    ds R" ""
+.    ds C` ""
+.    ds C' ""
+'br\}
+.el\{\
+.    ds -- \|\(em\|
+.    ds PI \(*p
+.    ds L" ``
+.    ds R" ''
+'br\}
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
+.\" entries marked with X<> in POD.  Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.if \nF \{\
+.    de IX
+.    tm Index:\\$1\t\\n%\t"\\$2"
+..
+.    nr % 0
+.    rr F
+.\}
+.\"
+.\" For nroff, turn off justification.  Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.hy 0
+.if n .na
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear.  Run.  Save yourself.  No user-serviceable parts.
+.    \" fudge factors for nroff and troff
+.if n \{\
+.    ds #H 0
+.    ds #V .8m
+.    ds #F .3m
+.    ds #[ \f1
+.    ds #] \fP
+.\}
+.if t \{\
+.    ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+.    ds #V .6m
+.    ds #F 0
+.    ds #[ \&
+.    ds #] \&
+.\}
+.    \" simple accents for nroff and troff
+.if n \{\
+.    ds ' \&
+.    ds ` \&
+.    ds ^ \&
+.    ds , \&
+.    ds ~ ~
+.    ds /
+.\}
+.if t \{\
+.    ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+.    ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+.    ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+.    ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+.    ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+.    ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+.    \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+.    \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+.    \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+.    ds : e
+.    ds 8 ss
+.    ds o a
+.    ds d- d\h'-1'\(ga
+.    ds D- D\h'-1'\(hy
+.    ds th \o'bp'
+.    ds Th \o'LP'
+.    ds ae ae
+.    ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "Template::Tutorial::Datafile 3"
+.TH Template::Tutorial::Datafile 3 "2008-11-13" "perl v5.8.7" "User Contributed Perl Documentation"
+.SH "NAME"
+Template::Tutorial::Datafile \- Creating Data Output Files Using the Template Toolkit
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+.SH "Introducing the Template Toolkit"
+.IX Header "Introducing the Template Toolkit"
+There are a number of Perl modules that are universally 
+recognised as The Right Thing To Use for certain tasks. If you 
+accessed a database without using \s-1DBI\s0, pulled data from the \s-1WWW\s0 
+without using one of the \s-1LWP\s0 modules or parsed \s-1XML\s0 without using 
+XML::Parser or one of its subclasses then you'd run the risk of 
+being shunned by polite Perl society.
+.PP
+I believe that the year 2000 saw the emergence of another 'must 
+have' Perl module \- the Template Toolkit. I don't think I'm 
+alone in this belief as the Template Toolkit won the 'Best New 
+Module' award at the Perl Conference last summer. Version 2.0 of 
+the Template Toolkit (known as \s-1TT2\s0 to its friends) was recently 
+released to the \s-1CPAN\s0.
+.PP
+\&\s-1TT2\s0 was designed and written by Andy Wardley <abw@wardley.org>. 
+It was born out of Andy's previous templating module, 
+Text::Metatext, in best Fred Brooks 'plan to throw one away' 
+manner; and aims to be the most useful (or, at least, the most 
+\&\fIused\fR) Perl templating system.
+.PP
+\&\s-1TT2\s0 provides a way to take a file of fixed boilerplate text 
+(the template) and embed variable data within it. One obvious 
+use of this is in the creation of dynamic web pages and this is 
+where a lot of the attention that \s-1TT2\s0 has received has been 
+focussed. In this article, I hope to demonstrate that \s-1TT2\s0 is 
+just as useful in non-web applications.
+.SH "Using the Template Toolkit"
+.IX Header "Using the Template Toolkit"
+Let's look at how we'd use \s-1TT2\s0 to process a simple data file. 
+\&\s-1TT2\s0 is an object oriented Perl module. Having downloaded it from 
+\&\s-1CPAN\s0 and installed it in the usual manner, using it in your 
+program is as easy as putting the lines
+.PP
+.Vb 2
+\&    use Template;
+\&    my $tt = Template\->new;
+.Ve
+.PP
+in your code. The constructor function, \f(CW\*(C`new\*(C'\fR, takes 
+a number of optional parameters which are documented in the 
+copious manual pages that come with the module, but for the 
+purposes of this article we'll keep things as simple as 
+possible.
+.PP
+To process the template, you would call the \f(CW\*(C`process\*(C'\fR method 
+like this
+.PP
+.Vb 2
+\&    $tt\->process('my_template', \e%data)
+\&        || die $tt\->error;
+.Ve
+.PP
+We pass two parameters to \f(CW\*(C`process\*(C'\fR, the first is the name of 
+the file containing the template to process (in this case, 
+my_template) and the second is a reference to a hash which 
+contains the data items that you want to use in the template. If 
+processing the template gives  any kind of error, the program 
+will die with a (hopefully) useful error message.
+.PP
+So what kinds of things can go in \f(CW%data\fR? The answer is just 
+about anything. Here's an example showing data about English 
+Premier League football teams.
+.PP
+.Vb 10
+\&    my @teams = ({ name   => 'Man Utd',
+\&                   played => 16,
+\&                   won    => 12,
+\&                   drawn  => 3,
+\&                   lost   => 1 },
+\&                 { name   => 'Bradford',
+\&                   played => 16,
+\&                   won    => 2,
+\&                   drawn  => 5,
+\&                   lost   => 9 });
+.Ve
+.PP
+.Vb 3
+\&    my %data = ( name   => 'English Premier League',
+\&                 season => '2000/01',
+\&                 teams  => \e@teams );
+.Ve
+.PP
+This creates three data items which can be accessed within the 
+template, called \f(CW\*(C`name\*(C'\fR, \f(CW\*(C`season\*(C'\fR and \f(CW\*(C`teams\*(C'\fR. Notice that 
+\&\f(CW\*(C`teams\*(C'\fR is a complex data structure.
+.PP
+Here is a template that we might use to process this data.
+.PP
+.Vb 1
+\&    League Standings
+.Ve
+.PP
+.Vb 2
+\&    League Name: [% name %]
+\&    Season     : [% season %]
+.Ve
+.PP
+.Vb 5
+\&    Teams:
+\&    [% FOREACH team = teams \-%]
+\&    [% team.name %] [% team.played \-%] 
+\&     [% team.won %] [% team.drawn %] [% team.lost %]
+\&    [% END %]
+.Ve
+.PP
+Running this template with this data gives us the following 
+output
+.PP
+.Vb 1
+\&                League Standings
+.Ve
+.PP
+.Vb 2
+\&    League Name: English Premier League
+\&    Season     : 2000/01
+.Ve
+.PP
+.Vb 3
+\&    Teams:
+\&    Man Utd 16 12 3 1
+\&    Bradford 16 2 5 9
+.Ve
+.PP
+Hopefully the syntax of the template is simple enough to 
+follow. There are a few points to note.
+.IP "\(bu" 4
+Template processing directives are written using a simple 
+language which is not Perl.
+.IP "\(bu" 4
+The keys of the \f(CW%data\fR have become the names of the data 
+variables within the template.
+.IP "\(bu" 4
+Template processing directives are surrounded by \f(CW\*(C`[%\*(C'\fR and 
+\&\f(CW\*(C`%]\*(C'\fR sequences.
+.IP "\(bu" 4
+If these tags are replaced with \f(CW\*(C`[%\-\*(C'\fR \f(CW\*(C`\-%]\*(C'\fR then the preceding 
+or following linefeed is suppressed.
+.IP "\(bu" 4
+In the \f(CW\*(C`FOREACH\*(C'\fR loop, each element of the \f(CW\*(C`teams\*(C'\fR list was 
+assigned, in turn, to the temporary variable \f(CW\*(C`team\*(C'\fR.
+.IP "\(bu" 4
+Each item assigned to the \f(CW\*(C`team\*(C'\fR variable is a Perl hash. 
+Individual values within the hash are accessed using a dot notation.
+.PP
+It's probably the first and last of these points which are the 
+most important. The first point emphasises the separation of the 
+data acquisition logic from the presentation logic. The person 
+creating the presentation template doesn't need to know Perl, 
+they only need to know the data items which will be passed into
+the template.
+.PP
+The last point demonstrates the way that \s-1TT2\s0 protects the 
+template designer from the implementation of the data structures.
+The data objects passed to the template processor can be scalars,
+arrays, hashes, objects or even subroutines. The template 
+processor will just interpret your data correctly and Do The 
+Right Thing to return the correct value to you. In this example 
+each team was a hash, but in a larger system each team might be 
+an object, in which case \f(CW\*(C`name\*(C'\fR, \f(CW\*(C`played\*(C'\fR, etc. would be accessor 
+methods to the underlying object attributes. No changes would be 
+required to the template as the template processor would realise 
+that it needed to call methods rather than access hash values.
+.Sh "A more complex example"
+.IX Subsection "A more complex example"
+Stats about the English Football League are usually presented in
+a slightly more complex format than the one we used above. A 
+full set of stats will show the number of games that a team has 
+won, lost or drawn, the number of goals scored for and against 
+the team and the number of points that the team therefore has.
+Teams gain three points for a win and one point for a draw. When
+teams have the same number of points they are separated by the 
+goal difference, that is the number of goals the team has scored
+minus the number of team scored against them. To complicate 
+things even further, the games won, drawn and lost and the goals 
+for and against are often split between home and away games.
+.PP
+Therefore if you have a data source which lists the team name 
+togther with the games won, drawn and lost and the goals for and 
+against split into home and away (a total of eleven data items) 
+you can calculate all of the other items (goal difference, 
+points awarded and even position in the league). Let's take such 
+a file, but we'll only look at the top three teams. It will look 
+something like this:
+.PP
+.Vb 3
+\&    Man Utd,7,1,0,26,4,5,2,1,15,6
+\&    Arsenal,7,1,0,17,4,2,3,3,7,9
+\&    Leicester,4,3,1,10,8,4,2,2,7,4
+.Ve
+.PP
+A simple script to read this data into an array of hashes will 
+look something like this (I've simplified the names of the data 
+columns \- w, d, and l are games won, drawn and lost and f and a 
+are goals scored for and against; h and a at the front of a data 
+item name indicates whether it's a home or away statistic):
+.PP
+.Vb 1
+\&    my @cols = qw(name hw hd hl hf ha aw ad al af aa);
+.Ve
+.PP
+.Vb 3
+\&    my @teams;
+\&    while (<>) {
+\&        chomp;
+.Ve
+.PP
+.Vb 1
+\&        my %team;
+.Ve
+.PP
+.Vb 1
+\&        @team{@cols} = split /,/;
+.Ve
+.PP
+.Vb 2
+\&        push @teams, \e%team;
+\&    }
+.Ve
+.PP
+We can then go thru the teams again and calculate all of the 
+derived data items:
+.PP
+.Vb 4
+\&    foreach (@teams) {
+\&        $_\->{w} = $_\->{hw} + $_\->{aw};
+\&        $_\->{d} = $_\->{hd} + $_\->{ad};
+\&        $_\->{l} = $_\->{hl} + $_\->{al};
+.Ve
+.PP
+.Vb 1
+\&        $_\->{pl} = $_\->{w} + $_\->{d} + $_\->{l};
+.Ve
+.PP
+.Vb 2
+\&        $_\->{f} = $_\->{hf} + $_\->{af};
+\&        $_\->{a} = $_\->{ha} + $_\->{aa};
+.Ve
+.PP
+.Vb 3
+\&        $_\->{gd} = $_\->{f} \- $_\->{a};
+\&        $_\->{pt} = (3 * $_\->{w}) + $_\->{d};
+\&    }
+.Ve
+.PP
+And then produce a list sorted in descending order:
+.PP
+.Vb 3
+\&    @teams = sort { 
+\&        $b\->{pt} <=> $b\->{pt} || $b\->{gd} <=> $a\->{gd} 
+\&    } @teams;
+.Ve
+.PP
+And finally add the league position data item:
+.PP
+.Vb 2
+\&    $teams[$_]\->{pos} = $_ + 1 
+\&        foreach 0 .. $#teams;
+.Ve
+.PP
+Having pulled all of our data into an internal data structure 
+we can start to produce output using out templates. A template 
+to create a \s-1CSV\s0 file containing the data split between home and 
+away stats would look like this:
+.PP
+.Vb 6
+\&    [% FOREACH team = teams \-%]
+\&    [% team.pos %],[% team.name %],[% team.pl %],[% team.hw %],
+\&    [%\- team.hd %],[% team.hl %],[% team.hf %],[% team.ha %],
+\&    [%\- team.aw %],[% team.ad %],[% team.al %],[% team.af %],
+\&    [%\- team.aa %],[% team.gd %],[% team.pt %]
+\&    [%\- END %]
+.Ve
+.PP
+And processing it like this:
+.PP
+.Vb 2
+\&    $tt\->process('split.tt', { teams => \e@teams }, 'split.csv')
+\&      || die $tt\->error;
+.Ve
+.PP
+produces the following output:
+.PP
+.Vb 3
+\&    1,Man Utd,16,7,1,0,26,4,5,2,1,15,6,31,39
+\&    2,Arsenal,16,7,1,0,17,4,2,3,3,7,9,11,31
+\&    3,Leicester,16,4,3,1,10,8,4,2,2,7,4,5,29
+.Ve
+.PP
+Notice that we've introduced the third parameter to \f(CW\*(C`process\*(C'\fR. 
+If this parameter is missing then the \s-1TT2\s0 sends its output to 
+\&\f(CW\*(C`STDOUT\*(C'\fR. If this parameter is a scalar then it is taken as the 
+name of a file to write the output to. This parameter can also be 
+(amongst other things) a filehandle or a reference to an object w
+hich is assumed to implement a \f(CW\*(C`print\*(C'\fR method.
+.PP
+If we weren't interested in the split between home and away games, 
+then we could use a simpler template like this:
+.PP
+.Vb 5
+\&    [% FOREACH team = teams \-%]
+\&    [% team.pos %],[% team.name %],[% team.pl %],[% team.w %],
+\&    [%\- team.d %],[% team.l %],[% team.f %],[% team.a %],
+\&    [%\- team.aa %],[% team.gd %],[% team.pt %]
+\&    [% END \-%]
+.Ve
+.PP
+Which would produce output like this:
+.PP
+.Vb 3
+\&    1,Man Utd,16,12,3,1,41,10,6,31,39
+\&    2,Arsenal,16,9,4,3,24,13,9,11,31
+\&    3,Leicester,16,8,5,3,17,12,4,5,29
+.Ve
+.SH "Producing XML"
+.IX Header "Producing XML"
+This is starting to show some of the power and flexibility of 
+\&\s-1TT2\s0, but you may be thinking that you could just as easily produce 
+this output with a \f(CW\*(C`foreach\*(C'\fR loop and a couple of \f(CW\*(C`print\*(C'\fR 
+statements in your code. This is, of course, true; but that's 
+because I've chosen a deliberately simple example to explain the 
+concepts. What if we wanted to produce an \s-1XML\s0 file containing the 
+data? And what if (as I mentioned earlier) the league data was held 
+in an object? The code would then look even easier as most of the code 
+we've written earlier would be hidden away in \f(CW\*(C`FootballLeague.pm\*(C'\fR.
+.PP
+.Vb 2
+\&    use FootballLeague;
+\&    use Template;
+.Ve
+.PP
+.Vb 1
+\&    my $league = FootballLeague\->new(name => 'English Premier');
+.Ve
+.PP
+.Vb 1
+\&    my $tt = Template\->new;
+.Ve
+.PP
+.Vb 2
+\&    $tt\->process('league_xml.tt', { league => $league })
+\&        || die $tt\->error;
+.Ve
+.PP
+And the template in \f(CW\*(C`league_xml.tt\*(C'\fR would look something like this:
+.PP
+.Vb 2
+\&    <?xml version="1.0"?>
+\&    <!DOCTYPE LEAGUE SYSTEM "league.dtd">
+.Ve
+.PP
+.Vb 22
+\&    <league name="[% league.name %]" season="[% league.season %]">
+\&    [% FOREACH team = league.teams \-%]
+\&      <team name="[% team.name %]"
+\&            pos="[% team.pos %]"
+\&            played="[% team.pl %]"
+\&            goal_diff="[% team.gd %]"
+\&            points="[% team.pt %]">
+\&         <stats type="home">
+\&                win="[% team.hw %]"
+\&                draw="[%\- team.hd %]"
+\&                lose="[% team.hl %]"
+\&                for="[% team.hf %]"
+\&                against="[% team.ha %]" />
+\&         <stats type="away">
+\&                win="[% team.aw %]"
+\&                draw="[%\- team.ad %]"
+\&                lose="[% team.al %]"
+\&                for="[% team.af %]"
+\&                against="[% team.aa %]" />
+\&      </team>
+\&    [% END \-%]
+\&    &/league>
+.Ve
+.PP
+Notice that as we've passed the whole object into \f(CW\*(C`process\*(C'\fR then 
+we need to put an extra level of indirection on our template 
+variables \- everything is now a component of the \f(CW\*(C`league\*(C'\fR variable. 
+Other than that, everything in the template is very similar to what 
+we've used before. Presumably now \f(CW\*(C`team.name\*(C'\fR calls an accessor 
+function rather than carrying out a hash lookup, but all of this 
+is transparent to our template designer.
+.SH "Multiple Formats"
+.IX Header "Multiple Formats"
+As a final example, let's suppose that we need to create output
+football league tables in a number of formats. Perhaps we are 
+passing this data on to other people and they can't all use the 
+same format. Some of our users need \s-1CSV\s0 files and others need 
+\&\s-1XML\s0. Some require data split between home and away matches and 
+other just want the totals. In total, then, we'll need four 
+different templates, but the good news is that they can use the 
+same data object. All the script needs to do is to establish 
+which template is required and process it.
+.PP
+.Vb 2
+\&    use FootballLeague;
+\&    use Template;
+.Ve
+.PP
+.Vb 1
+\&    my ($name, $type, $stats) = @_;
+.Ve
+.PP
+.Vb 1
+\&    my $league = FootballLeague\->new(name => $name);
+.Ve
+.PP
+.Vb 1
+\&    my $tt = Template\->new;
+.Ve
+.PP
+.Vb 4
+\&    $tt\->process("league_${type}_$stats.tt", 
+\&                 { league => $league }
+\&                 "league_$stats.$type")
+\&        || die $tt\->error;
+.Ve
+.PP
+For example, you can call this script as
+.PP
+.Vb 1
+\&    league.pl 'English Premier' xml split
+.Ve
+.PP
+This will process a template called \f(CW\*(C`league_xml_split.tt\*(C'\fR 
+and put the results in a file called \f(CW\*(C`league_split.xml\*(C'\fR.
+.PP
+This starts to show the true strength of the Template Toolkit. 
+If we later wanted to add another file format \- perhaps we 
+wanted to create a league table \s-1HTML\s0 page or even a LaTeX 
+document \- then we would just need to create the appropriate 
+template and name it according to our existing naming 
+convention. We would need to make no changes to the code.
+.PP
+I hope you can now see why the Template Toolkit is fast becoming
+an essential part of many people's Perl installation.
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+Dave Cross <dave@dave.org.uk>
+.SH "VERSION"
+.IX Header "VERSION"
+Template Toolkit version 2.19, released on 27 April 2007.
+.SH "COPYRIGHT"
+.IX Header "COPYRIGHT"
+Copyright (C) 2001 Dave Cross <dave@dave.org.uk>
+.PP
+This module is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.