File Coverage

lib/Template.pm
Criterion Covered Total %
statement 82 87 94.2
branch 31 40 77.5
condition 22 30 73.3
subroutine 17 17 100.0
pod 4 4 100.0
total 156 178 87.6


line stmt bran cond sub pod time code
1             #============================================================= -*-perl-*-
2             #
3             # Template
4             #
5             # DESCRIPTION
6             # Module implementing a simple, user-oriented front-end to the Template
7             # Toolkit.
8             #
9             # AUTHOR
10             # Andy Wardley
11             #
12             # COPYRIGHT
13             # Copyright (C) 1996-2014 Andy Wardley. All Rights Reserved.
14             #
15             # This module is free software; you can redistribute it and/or
16             # modify it under the same terms as Perl itself.
17             #
18             #========================================================================
19              
20             package Template;
21              
22 92     92   26775 use strict;
  92         96  
  92         2002  
23 92     92   257 use warnings;
  92         89  
  92         1581  
24 92     92   1765 use 5.006;
  92         205  
25 92     92   310 use base 'Template::Base';
  92         94  
  92         26488  
26              
27 92     92   26716 use Template::Config;
  92         130  
  92         2461  
28 92     92   405 use Template::Constants;
  92         82  
  92         4118  
29 92     92   35059 use Template::Provider;
  92         146  
  92         2435  
30 92     92   27325 use Template::Service;
  92         147  
  92         2061  
31 92     92   412 use File::Basename;
  92         94  
  92         4860  
32 92     92   341 use File::Path;
  92         92  
  92         3571  
33 92     92   336 use Scalar::Util qw(blessed);
  92         95  
  92         63503  
34              
35             our $VERSION = '2.27';
36             our $ERROR = '';
37             our $DEBUG = 0;
38             our $BINMODE = 0 unless defined $BINMODE;
39             our $AUTOLOAD;
40              
41             # preload all modules if we're running under mod_perl
42             Template::Config->preload() if $ENV{ MOD_PERL };
43              
44              
45             #------------------------------------------------------------------------
46             # process($input, \%replace, $output)
47             #
48             # Main entry point for the Template Toolkit. The Template module
49             # delegates most of the processing effort to the underlying SERVICE
50             # object, an instance of the Template::Service class.
51             #------------------------------------------------------------------------
52              
53             sub process {
54 1227     1227 1 8931 my ($self, $template, $vars, $outstream, @opts) = @_;
55 1227         906 my ($output, $error);
56 1227 100 66     3591 my $options = (@opts == 1) && ref($opts[0]) eq 'HASH'
57             ? shift(@opts) : { @opts };
58              
59             $options->{ binmode } = $BINMODE
60 1227 100       3564 unless defined $options->{ binmode };
61              
62             # we're using this for testing in t/output.t and t/filter.t so
63             # don't remove it if you don't want tests to fail...
64 1227 50 66     2026 $self->DEBUG("set binmode\n") if $DEBUG && $options->{ binmode };
65              
66 1227         3200 $output = $self->{ SERVICE }->process($template, $vars);
67              
68 1227 100       2258 if (defined $output) {
69 1222   66     2091 $outstream ||= $self->{ OUTPUT };
70 1222 100       2198 unless (ref $outstream) {
71 4         5 my $outpath = $self->{ OUTPUT_PATH };
72 4 50       10 $outstream = "$outpath/$outstream" if $outpath;
73             }
74              
75             # send processed template to output stream, checking for error
76 1222 50       2372 return ($self->error($error))
77             if ($error = &_output($outstream, \$output, $options));
78              
79 1222         4090 return 1;
80             }
81             else {
82 5         14 return $self->error($self->{ SERVICE }->error);
83             }
84             }
85              
86              
87             #------------------------------------------------------------------------
88             # service()
89             #
90             # Returns a reference to the internal SERVICE object which handles
91             # all requests for this Template object
92             #------------------------------------------------------------------------
93              
94             sub service {
95 2     2 1 5 my $self = shift;
96 2         7 return $self->{ SERVICE };
97             }
98              
99              
100             #------------------------------------------------------------------------
101             # context()
102             #
103             # Returns a reference to the CONTEXT object within the SERVICE
104             # object.
105             #------------------------------------------------------------------------
106              
107             sub context {
108 8     8 1 36 my $self = shift;
109 8         33 return $self->{ SERVICE }->{ CONTEXT };
110             }
111              
112             sub template {
113 1     1 1 10 shift->context->template(@_);
114             }
115              
116              
117             #========================================================================
118             # -- PRIVATE METHODS --
119             #========================================================================
120              
121             #------------------------------------------------------------------------
122             # _init(\%config)
123             #------------------------------------------------------------------------
124             sub _init {
125 154     154   230 my ($self, $config) = @_;
126              
127             # convert any textual DEBUG args to numerical form
128 154         270 my $debug = $config->{ DEBUG };
129 154 100 50     598 $config->{ DEBUG } = Template::Constants::debug_flags($self, $debug)
      100        
130             || return if defined $debug && $debug !~ /^\d+$/;
131              
132             # prepare a namespace handler for any CONSTANTS definition
133 154 100       592 if (my $constants = $config->{ CONSTANTS }) {
134 7   100     31 my $ns = $config->{ NAMESPACE } ||= { };
135 7   100     29 my $cns = $config->{ CONSTANTS_NAMESPACE } || 'constants';
136 7   50     33 $constants = Template::Config->constants($constants)
137             || return $self->error(Template::Config->error);
138 7         20 $ns->{ $cns } = $constants;
139             }
140              
141             $self->{ SERVICE } = $config->{ SERVICE }
142 154   50     1034 || Template::Config->service($config)
143             || return $self->error(Template::Config->error);
144              
145 154   100     683 $self->{ OUTPUT } = $config->{ OUTPUT } || \*STDOUT;
146 154         216 $self->{ OUTPUT_PATH } = $config->{ OUTPUT_PATH };
147              
148 154         691 return $self;
149             }
150              
151              
152             #------------------------------------------------------------------------
153             # _output($where, $text)
154             #------------------------------------------------------------------------
155              
156             sub _output {
157 1223     1223   1343 my ($where, $textref, $options) = @_;
158 1223         913 my $reftype;
159 1223         1039 my $error = 0;
160              
161             # call a CODE reference
162 1223 100 66     3581 if (($reftype = ref($where)) eq 'CODE') {
    50          
    100          
    100          
    100          
    50          
163 1         4 &$where($$textref);
164             }
165             # print to a glob (such as \*STDOUT)
166             elsif ($reftype eq 'GLOB') {
167 0         0 print $where $$textref;
168             }
169             # append output to a SCALAR ref
170             elsif ($reftype eq 'SCALAR') {
171 1215         1647 $$where .= $$textref;
172             }
173             # push onto ARRAY ref
174             elsif ($reftype eq 'ARRAY') {
175 1         3 push @$where, $$textref;
176             }
177             # call the print() method on an object that implements the method
178             # (e.g. IO::Handle, Apache::Request, etc)
179             elsif (blessed($where) && $where->can('print')) {
180 1         3 $where->print($$textref);
181             }
182             # a simple string is taken as a filename
183             elsif (! $reftype) {
184 5         10 local *FP;
185             # make destination directory if it doesn't exist
186 5         157 my $dir = dirname($where);
187 5 50       7 eval { mkpath($dir) unless -d $dir; };
  5         90  
188 5 50       369 if ($@) {
    50          
189             # strip file name and line number from error raised by die()
190 0         0 ($error = $@) =~ s/ at \S+ line \d+\n?$//;
191             }
192             elsif (open(FP, ">$where")) {
193             # binmode option can be 1 or a specific layer, e.g. :utf8
194 5         8 my $bm = $options->{ binmode };
195 5 100 66     28 if ($bm && $bm eq 1) {
    50          
196 2         4 binmode FP;
197             }
198             elsif ($bm){
199 0         0 binmode FP, $bm;
200             }
201 5         33 print FP $$textref;
202 5         187 close FP;
203             }
204             else {
205 0         0 $error = "$where: $!";
206             }
207             }
208             # give up, we've done our best
209             else {
210 0         0 $error = "output_handler() cannot determine target type ($where)\n";
211             }
212              
213 1223         2478 return $error;
214             }
215              
216              
217             1;
218              
219             __END__