File Coverage

blib/lib/Text/SimpleTemplate.pm
Criterion Covered Total %
statement 54 55 98.1
branch 12 16 75.0
condition 9 14 64.2
subroutine 10 10 100.0
pod 5 5 100.0
total 90 100 90.0


line stmt bran cond sub pod time code
1             # -*- mode: perl -*-
2             #
3             # $Id: SimpleTemplate.pm,v 1.7 1999/10/24 13:33:44 tai Exp $
4             #
5              
6             package Text::SimpleTemplate;
7              
8             =head1 NAME
9              
10             Text::SimpleTemplate - Yet another module for template processing
11              
12             =head1 SYNOPSIS
13              
14             use Text::SimpleTemplate;
15              
16             $tmpl = new Text::SimpleTemplate; # create processor object
17             $tmpl->setq(TEXT => "hello, world"); # export data to template
18             $tmpl->load($file); # loads template from named file
19             $tmpl->pack(q{TEXT: <% $TEXT; %>}); # loads template from in-memory data
20              
21             print $tmpl->fill; # prints "TEXT: hello, world"
22              
23             =head1 DESCRIPTION
24              
25             This is yet another library for template-based text generation.
26              
27             Template-based text generation is a way to separate program code
28             and data, so non-programmer can control final result (like HTML) as
29             desired without tweaking the program code itself. By doing so, jobs
30             like website maintenance is much easier because you can leave program
31             code unchanged even if page redesign was needed.
32              
33             The idea is simple. Whenever a block of text surrounded by '<%' and
34             '%>' (or any pair of delimiters you specify) is found, it will be
35             taken as Perl expression, and will be replaced by its evaluated result.
36              
37             Major goal of this library is simplicity and speed. While there're
38             many modules for template processing, this module has near raw
39             Perl-code (i.e., "s|xxx|xxx|ge") speed, while providing simple-to-use
40             objective interface.
41              
42             =head1 INSTALLATION / REQUIREMENTS
43              
44             This module requires Carp.pm and FileHandle.pm.
45             Since these are standard modules, all you need is perl itself.
46              
47             For installation, standard procedure of
48              
49             perl Makefile.PL
50             make
51             make test
52             make install
53              
54             should work just fine.
55              
56             =head1 TEMPLATE SYNTAX AND USAGE
57              
58             Suppose you have a following template named "sample.tmpl":
59              
60             === Module Information ===
61             Name: <% $INFO->{Name}; %>
62             Description: <% $INFO->{Description}; %>
63             Author: <% $INFO->{Author}; %> <<% $INFO->{Email}; %>>
64              
65             With the following code...
66              
67             use Safe;
68             use Text::SimpleTemplate;
69              
70             $tmpl = new Text::SimpleTemplate;
71             $tmpl->setq(INFO => {
72             Name => "Text::SimpleTemplate",
73             Description => "Yet another module for template processing",
74             Author => "Taisuke Yamada",
75             Email => "tai\@imasy.or.jp",
76             });
77             $tmpl->load("sample.tmpl");
78              
79             print $tmpl->fill(PACKAGE => new Safe);
80              
81             ...you will get following result:
82              
83             === Module Information ===
84             Name: Text::SimpleTemplate
85             Description: Yet another module for template processing
86             Author: Taisuke Yamada
87              
88             As you might have noticed, any scalar data can be exported
89             to template namespace, even hash reference or code reference.
90              
91             By the way, although I used "Safe" module in example above,
92             this is not a requirement. However, if you want to control
93             power of the template editor over program logic, its use is
94             strongly recommended (see L for more).
95              
96             =head1 DIRECT ACCESS TO TEMPLATE NAMESPACE
97              
98             In addition to its native interface, you can also access
99             directly to template namespace.
100              
101             $FOO::text = 'hello, world';
102             @FOO::list = qw(foo bar baz);
103              
104             $tmpl = new Text::SimpleTemplate;
105             $tmpl->pack(q{TEXT: <% $text; %>, LIST: <% "@list"; %>});
106              
107             print $tmpl->fill(PACKAGE => 'FOO');
108              
109             While I don't recommend this style, this might be useful if you
110             want to export list, hash, or subroutine directly without using
111             reference.
112              
113             =head1 METHODS
114              
115             Following methods are currently available.
116              
117             =over 4
118              
119             =cut
120              
121 10     10   97058 use Carp;
  10         25  
  10         1023  
122 10     10   9238 use FileHandle;
  10         316724  
  10         70  
123              
124 10     10   10173 use strict;
  10         31  
  10         394  
125 10     10   55 use vars qw($DEBUG $VERSION);
  10         24  
  10         6965  
126              
127             $DEBUG = 0;
128             $VERSION = '0.36';
129              
130             =item $tmpl = Text::SimpleTemplate->new;
131              
132             Constructor. Returns newly created object.
133              
134             If this method was called through existing object, cloned object
135             will be returned. This cloned instance inherits all properties
136             except for internal buffer which holds template data. Cloning is
137             useful for chained template processing.
138              
139             =cut
140             sub new {
141 10     10 1 203 my $name = shift;
142 10   66     114 my $self = bless { hash => {} }, ref($name) || $name;
143              
144 10 100       65 return $self unless ref($name);
145              
146             ## inherit parent configuration
147 1         2 while (my($k, $v) = each %{$name}) {
  4         14  
148 3 100       9 $self->{$k} = $v unless $k eq 'buff';
149             }
150 1         3 return $self;
151             }
152              
153             =item $tmpl->setq($name => $data, $name => $data, ...);
154              
155             Exports scalar data ($data) to template namespace,
156             with $name as a scalar variable name to be used in template.
157              
158             You can repeat the pair to export multiple sets in one operation.
159              
160             =cut
161             sub setq {
162 5     5 1 30 my $self = shift;
163 5         23 my %pair = @_;
164              
165 5         39 while (my($key, $val) = each %pair) {
166 5         53 $self->{hash}->{$key} = $val;
167             }
168             }
169              
170             =item $tmpl->load($file, %opts);
171              
172             Loads template file ($file) for later evaluation.
173             File can be specified in either form of pathname or fileglob.
174              
175             This method accepts DELIM option, used to specify delimiter
176             for parsing template. It is speficied by passing reference
177             to array containing delimiter pair, just like below:
178              
179             $tmpl->load($file, DELIM => [qw()]);
180              
181             Returns object reference to itself.
182              
183             =cut
184             sub load {
185 1     1 1 169 my $self = shift;
186 1         3 my $file = shift;
187              
188 1 50 33     31 $file = new FileHandle($file) || croak($!) unless ref($file);
189 1         221 $self->pack(join("", <$file>), @_);
190             }
191              
192             =item $tmpl->pack($data, %opts);
193              
194             Loads in-memory data ($data) for later evaluation.
195             Except for this difference, works just like $tmpl->load.
196              
197             =cut
198             sub pack {
199 16     16 1 217 my $self = shift; $self->{buff} = shift;
  16         67  
200 16         41 my %opts = @_;
201              
202             ##
203             ## I used to build internal document structure here, but
204             ## it seems it's much faster to just make a copy and let
205             ## Perl do the parsing on every evaluation stage. Hmm...
206             ##
207              
208 16 50       82 $self->{DELIM} = [@{$opts{LR_CHAR}}] if $opts{LR_CHAR};
  0         0  
209 16 100       61 $self->{DELIM} = [map { quotemeta } @{$opts{DELIM}}] if $opts{DELIM};
  2         9  
  1         3  
210 16   100     102 $self->{DELIM} ||= [qw(<% %>)];
211 16         92 $self;
212             }
213              
214             =item $text = $tmpl->fill(%opts);
215              
216             Returns evaluated result of template, which was
217             preloaded by either $tmpl->pack or $tmpl->load method.
218              
219             This method accepts two options: PACKAGE and OHANDLE.
220              
221             PACKAGE option specifies the namespace where template
222             evaluation takes place. You can either pass the name of
223             the package, or the package object itself. So either of
224              
225             $tmpl->fill(PACKAGE => new Safe);
226             $tmpl->fill(PACKAGE => new Some::Module);
227             $tmpl->fill(PACKAGE => 'Some::Package');
228              
229             works. In case Safe module (or its subclass) was passed,
230             its "reval" method will be used instead of built-in eval.
231              
232             OHANDLE option is for output selection. By default, this
233             method returns the result of evaluation, but with OHANDLE
234             option set, you can instead make it print to given handle.
235             Either style of
236              
237             $tmpl->fill(OHANDLE => \*STDOUT);
238             $tmpl->fill(OHANDLE => new FileHandle(...));
239              
240             is supported.
241              
242             =cut
243             sub fill {
244 16     16 1 2352 my $self = shift;
245 16         40 my %opts = @_;
246 16   66     105 my $from = $opts{PACKAGE} || caller;
247 16         30 my $hand = $opts{OHANDLE};
248 16         27 my $buff;
249             my $name;
250              
251 10     10   63 no strict;
  10         17  
  10         2010  
252              
253             ## determine package namespace to do the evaluation
254 16 100       139 if (UNIVERSAL::isa($from, 'Safe')) {
255 2         947 $name = $from->root;
256             }
257             else {
258 14   66     84 $name = ref($from) || $from;
259             }
260              
261 16         56 my $L = $self->{DELIM}->[0];
262 16         33 my $R = $self->{DELIM}->[1];
263              
264             ## copy to save original
265 16         34 $buff = $self->{buff};
266              
267             ## export, parse, and evaluate
268 16         14625 eval qq{package $name;} . q{
269             ## export stored data to target namespace
270             while (my($key, $val) = each %{$self->{hash}}) {
271             #print STDERR "Exporting to \$${name}::${key}: $val\n";
272             $ {"${key}"} = $val;
273             }
274              
275             #print STDERR "\nBEFORE: $buff\n";
276             if (UNIVERSAL::isa($from, 'Safe')) {
277             $buff =~ s|$L(.*?)$R|$from->reval($1)|ges;
278             }
279             else {
280             $buff =~ s|$L(.*?)$R|eval($1)|ges;
281             }
282             #print STDERR "\nAFTER: $buff\n";
283             };
284 16 50       1244 $buff = $@ if $@;
285              
286 16 50       49 print $hand $buff if $hand; $buff;
  16         159  
287             }
288              
289             =back
290              
291             =head1 NOTES / BUGS
292              
293             Nested template delimiter will cause this module to fail.
294              
295             =head1 CONTACT ADDRESS
296              
297             Please send any bug reports/comments to .
298              
299             =head1 AUTHORS / CONTRIBUTORS
300              
301             - Taisuke Yamada
302             - Lin Tianshan
303              
304             =head1 COPYRIGHT
305              
306             Copyright 1999-2001. All rights reserved.
307              
308             This library is free software; you can redistribute it
309             and/or modify it under the same terms as Perl itself.
310              
311             =cut
312              
313             1;