File Coverage

blib/lib/Tenjin/Context.pm
Criterion Covered Total %
statement 43 56 76.7
branch 6 18 33.3
condition 2 8 25.0
subroutine 11 12 91.6
pod 3 3 100.0
total 65 97 67.0


line stmt bran cond sub pod time code
1             package Tenjin::Context;
2              
3 8     8   27 use strict;
  8         20  
  8         173  
4 8     8   21 use warnings;
  8         8  
  8         130  
5 8     8   2572 use Tenjin::Util;
  8         12  
  8         182  
6 8     8   32 use Carp;
  8         8  
  8         1189  
7              
8             our $VERSION = "1.000001";
9             $VERSION = eval $VERSION;
10              
11             =head1 NAME
12              
13             Tenjin::Context - In charge of managing variables passed to Tenjin templates.
14              
15             =head1 SYNOPSIS
16              
17             # this module is used internally, but if you insist, it is
18             # in charge of the context object:
19              
20             # in your templates (unnecessary, for illustration purposes):
21             [== $_context->{title} =]
22             # instead use:
23             [== $title =]
24              
25             =head1 DESCRIPTION
26              
27             This module is in charge of managing Perl variables that are passed to
28             templates upon rendering for direct usage. The context object is simply
29             a hash-ref of key-value pairs, which are made available for templates
30             as "standalone variables" named for each key in the hash-ref.
31              
32             This module is also in charge of the actual rendering of the templates,
33             or more correctly, for evaluating the Perl code created from the templates,
34             first integrating the context variables to them, and returning the rendered
35             output.
36              
37             Finally, this module makes the Tenjin utility methods of L
38             available natively inside templates. See L for more info.
39              
40             =head1 INTERNAL METHODS
41              
42             =head2 new( [\%vars] )
43              
44             Constructs a new context object, which is basically a hash-ref of key-value pairs
45             which are passed to templates as variables. If a C<$vars> hash-ref is passed
46             to the constructor, it will be augmented into the created object.
47              
48             To illustrate the context object, suppose it looks like so:
49              
50             {
51             scalar => 'I am a scalar',
52             arrayref => [qw/I am an array/],
53             hashref => { i => 'am', a => 'hash-ref' },
54             }
55              
56             Then the variables C<$scalar>, C<$arrayref> and C<$hashref> will be available for
57             direct usage inside your templates, and you can dereference the variables
58             normally (i.e. C<@$arrayref> and C<%$hashref>).
59              
60             =cut
61              
62             sub new {
63 13     13 1 19 my ($class, $self) = @_;
64              
65 13   50     21 $self ||= {};
66              
67 13         27 return bless $self, $class;
68             }
69              
70             =head2 evaluate( $script, $template_name )
71              
72             This method receives a compiled template and actually performes the evaluation
73             the renders it, then returning the rendered output. If Tenjin is configured
74             to C, the script will be Ced under C.
75              
76             =cut
77              
78             sub evaluate {
79 23     23 1 33 my ($self, $script, $name) = @_;
80              
81 23         23 my $_context = $self;
82 23 50 33     179 $script = ($script =~ /\A(.*)\Z/s) && $1 if $Tenjin::BYPASS_TAINT;
83 23 50       55 my $s = $name ? "# line 1 \"$name\"\n" : ''; # line directive
84 23         32 $s .= $script;
85              
86 23         20 my $ret;
87 23 50       33 if ($Tenjin::USE_STRICT) {
88 0         0 $ret = eval($s);
89 0         0 } else {
90 8     8   30 no strict;
  8         8  
  8         190  
91 23         4086 $ret = eval($s);
92 8     8   23 use strict;
  8         14  
  8         865  
93             }
94              
95 23 100       505 croak "[Tenjin] Failed rendering $name: $@" if $@;
96            
97 22         73 return $ret;
98             }
99              
100             =head2 to_func( $script, [$filename] )
101              
102             This method receives the script created when reading a template and wraps
103             it in a subroutine, Cs it and returns the rendered output. This method
104             is called when compiling the template.
105              
106             =cut
107              
108             sub to_func {
109 0     0 1 0 my ($self, $script, $name) = @_;
110              
111 0 0 0     0 $script = ($script =~ /\A(.*)\Z/s) && $1 if $Tenjin::BYPASS_TAINT;
112 0 0       0 my $s = $name ? "# line 1 \"$name\"\n" : ''; # line directive
113 0         0 $s .= "sub { my (\$_context) = \@_; $script }";
114            
115 0         0 my $ret;
116 0 0       0 if ($Tenjin::USE_STRICT) {
117 0         0 $ret = eval($s);
118 0         0 } else {
119 8     8   29 no strict;
  8         8  
  8         154  
120 0         0 $ret = eval($s);
121 8     8   22 use strict;
  8         6  
  8         1443  
122             }
123              
124 0 0       0 croak "[Tenjin] Failed compiling $name: $@" if $@;
125            
126 0         0 return $ret;
127             }
128              
129             =head2 _build_decl()
130              
131             This method is in charge of making all the key-value pairs of the context
132             object available to templates directly by the key names. This is simply done
133             by traversing the key-value pairs of the context object and adding an
134             assignment line between a scalar variable named as the key and its appropriate
135             value.
136              
137             =cut
138              
139             sub _build_decl {
140 23     23   22 my $self = shift;
141              
142 23         23 my $s = '';
143 23         78 foreach my $k (keys %$self) {
144 58 50       92 next if $k eq '_context';
145 58         121 $s .= "my \$$k = \$_context->{'$k'}; ";
146             }
147 23         84 return $s;
148             }
149              
150             =head1 UTILITY METHODS
151              
152             These methods are defined in L and used here so they are
153             made available natively inside templates. See L for more
154             information.
155              
156             =head2 _p( $expr )
157              
158             =head2 _P( $expr )
159              
160             =head2 escape( $expr )
161              
162             =head2 escape_xml( $expr )
163              
164             =head2 unescape_xml( $expr )
165              
166             =head2 encode_url( $url )
167              
168             =head2 decode_url( $url )
169              
170             =head2 checked( $expr )
171              
172             =head2 selected( $expr )
173              
174             =head2 disabled( $expr )
175              
176             =head2 nl2br( $text )
177              
178             =head2 text2html( $text )
179              
180             =head2 tagattr( $name, $expr, [$value] )
181              
182             =head2 tagattrs( %attrs )
183              
184             =head2 new_cycle( @items )
185              
186             =cut
187              
188             # this makes the Tenjin utility methods available to templates 'natively'
189             *_p = *Tenjin::Util::_p;
190             *_P = *Tenjin::Util::_P;
191             *escape = *Tenjin::Util::escape_xml;
192             *escape_xml = *Tenjin::Util::escape_xml;
193             *unescape_xml = *Tenjin::Util::unescape_xml;
194             *encode_url = *Tenjin::Util::encode_url;
195             *decode_url = *Tenjin::Util::decode_url;
196             *checked = *Tenjin::Util::checked;
197             *selected = *Tenjin::Util::selected;
198             *disabled = *Tenjin::Util::disabled;
199             *nl2br = *Tenjin::Util::nl2br;
200             *text2html = *Tenjin::Util::text2html;
201             *tagattr = *Tenjin::Util::tagattr;
202             *tagattrs = *Tenjin::Util::tagattrs;
203             *new_cycle = *Tenjin::Util::new_cycle;
204              
205             1;
206              
207             =head1 SEE ALSO
208              
209             L, L, L.
210              
211             =head1 AUTHOR, LICENSE AND COPYRIGHT
212              
213             See L.
214              
215             =cut