File Coverage

blib/lib/App/ZofCMS/Template.pm
Criterion Covered Total %
statement 12 151 7.9
branch 0 62 0.0
condition 0 27 0.0
subroutine 4 20 20.0
pod 1 14 7.1
total 17 274 6.2


line stmt bran cond sub pod time code
1              
2             package App::ZofCMS::Template;
3              
4 1     1   620 use strict;
  1         1  
  1         27  
5 1     1   3 use warnings;
  1         6  
  1         31  
6              
7             our $VERSION = '1.001006'; # VERSION
8              
9 1     1   3 use HTML::Template;
  1         1  
  1         16  
10              
11             require File::Spec;
12 1     1   3 use Carp;
  1         1  
  1         1084  
13              
14              
15             sub new {
16 0     0 0   my $class = shift;
17 0           my $config = shift;
18 0           my $self = bless {}, $class;
19 0           $self->config( $config );
20 0           $self->conf( $config->conf );
21 0           $self->query( $config->query );
22              
23 0           return $self;
24             }
25              
26             sub load {
27 0     0 0   my $self = shift;
28              
29 0           my $conf = $self->conf;
30 0           my $query = $self->query;
31              
32 0           my $template_file = File::Spec->catfile(
33             $conf->{templates},
34             $query->{dir},
35             $query->{page} . $conf->{zcms_template_extension},
36             );
37              
38 0 0         my $template = do $template_file
39             or croak "Failed to load template file [$template_file] ($!) ($@)";
40              
41 0           return $self->template( $template );
42             }
43              
44             sub prepare_defaults {
45 0     0 0   my $self = shift;
46              
47 0           my $template = $self->template;
48 0           my $conf = $self->conf;
49 0           my $query = $self->query;
50              
51 0   0       my $dir_defaults = $conf->{dir_defaults}{ $query->{dir} } || {};
52              
53 0           %$template = ( %$dir_defaults, %$template );
54 0 0         %$template = ( %{ $conf->{template_defaults} || {} }, %$template );
  0            
55              
56 0 0         %{ $template->{conf} } = (
  0            
57 0 0         %{ $conf->{template_defaults}{conf} || {} },
58 0 0         %{ $dir_defaults->{conf} || {} },
59 0           %{ $template->{conf} || {} },
60             );
61              
62 0 0         %{ $template->{t} } = (
  0            
63 0 0         %{ $conf->{template_defaults}{t} || {} },
64 0 0         %{ $dir_defaults->{t} || {} },
65 0           %{ $template->{t} || {} },
66             );
67              
68 0 0         %{ $template->{d} } = (
  0            
69 0 0         %{ $conf->{template_defaults}{d} || {} },
70 0 0         %{ $dir_defaults->{d} || {} },
71 0           %{ $template->{d} || {} },
72             );
73              
74 0 0         my @plug_keys = map /(\d+)/, grep /^plugins\d+$/,
75             keys %$template,
76 0           keys %{ $conf->{template_defaults} || {} },
77             keys %$dir_defaults;
78              
79 0           my %unique_plug_keys;
80 0           @unique_plug_keys{ @plug_keys } = ();
81 0           @plug_keys = sort { $a <=> $b } keys %unique_plug_keys;
  0            
82              
83 0           unshift @plug_keys, ''; # add this for 'plugins' key that doesn't have a number
84 0           $self->unique_plug_keys( \@plug_keys );
85              
86 0           for ( @plug_keys ) {
87 0   0       $template->{ "plugins$_" } = $self->sort_plugins(
      0        
      0        
88             ( $conf->{template_defaults}{ "plugins$_" } || [] ),
89             ( $dir_defaults->{ "plugins$_" } || [] ),
90             ( $template->{ "plugins$_" } || [] ),
91             );
92             }
93             }
94              
95             sub assemble {
96 0     0 0   my $self = shift;
97              
98 0           my $template = $self->template;
99 0           my $conf = $self->conf;
100 0           my $query = $self->query;
101              
102 0   0       my $html_template = HTML::Template->new(
103             filename => File::Spec->catfile(
104             $conf->{data_store},
105             $template->{conf}{base},
106             ),
107             die_on_bad_params => $template->{conf}{die_on_bad_params} || 0,
108             );
109              
110 0           my $data_store = $conf->{data_store};
111              
112 0           $self->_exec_plugins;
113              
114 0           $html_template->param( %{ $template->{t} } );
  0            
115              
116 0           while ( my ($key, $value) = each %$template ) {
117             next
118 0 0 0       if $key eq 'conf'
      0        
      0        
119             or $key eq 't'
120             or $key eq 'plugins'
121             or $key eq 'd';
122              
123 0 0         if ( ref $value eq 'SCALAR' ) {
124 0           my $file = File::Spec->catfile( $data_store, $$value );
125 0 0         if ( substr( $file, -5) eq '.tmpl' ) {
126 0   0       my $sub_html_template
127             = HTML::Template->new(
128             filename => $file,
129             die_on_bad_params
130             => $template->{conf}{die_on_bad_params} || 0,
131             );
132              
133 0           $sub_html_template->param( %{ $template->{t} } );
  0            
134              
135 0           $html_template->param( $key => $sub_html_template->output );
136             }
137             else {
138 0 0         open my $fh, '<', $file
139             or croak "Failed to open file [$file] for reading ($!)";
140              
141 0           $html_template->param( $key => do { local $/; <$fh>; } );
  0            
  0            
142 0           close $fh;
143             }
144             }
145             else {
146 0           $html_template->param( $key => $value );
147             }
148             }
149              
150 0           return $self->html_template( $html_template );
151             }
152              
153             sub execute_before {
154 0     0 0   return shift->_execute('before');
155             }
156             sub execute {
157 0     0 0   return shift->_execute;
158             }
159              
160             sub _execute {
161 0     0     my $self = shift;
162 0           my $is_before = shift;
163 0           my $template = $self->template;
164 0           my $conf = $self->conf;
165 0           my $query = $self->query;
166              
167 0 0         my $conf_key = $is_before ? 'exec_before' : 'exec';
168              
169 0 0 0       if ( ref $template->{conf}{ $conf_key } eq 'CODE' ) {
    0          
170 0           return $template->{conf}{ $conf_key }->(
171             $query,
172             $self->template,
173             $self->config,
174             $self->html_template,
175             );
176             }
177             elsif ( defined $template->{conf}{ $conf_key }
178             and length $template->{conf}{ $conf_key }
179             ) {
180 0           my $package = 'App::ZofCMS::Execs::' . $template->{conf}{ $conf_key };
181 0           eval "use $package;";
182 0 0         $@ and croak "Failed to use() module specified by the template "
183             . "[$package] Error: $@";
184              
185 0           return $package->new->execute(
186             $query,
187             $self->template,
188             $self->config,
189             $self->html_template,
190             );
191             }
192              
193 0           return 1;
194             }
195              
196              
197             sub _exec_plugins {
198 0     0     my $self = shift;
199 0           my $template = $self->template;
200 0           my $query = $self->query;
201 0           my $config = $self->config;
202              
203 0           for my $plug_key ( @{ $self->unique_plug_keys } ) {
  0            
204 0 0         for ( @{ $template->{ "plugins$plug_key" } || [] } ) {
  0            
205 0           my $plugin = "App::ZofCMS::Plugin::$_";
206 0           eval "use $plugin";
207 0 0         $@ and croak "Failed to use() plugin $plugin: $@";
208 0           $plugin->new->process( $template, $query, $config );
209             }
210             }
211              
212 0           return;
213             }
214              
215             sub sort_plugins {
216 0     0 0   my $self = shift;
217 0           my ( $conf_plugins, $dir_defaults_plugins, $template_plugins, ) = @_;
218              
219 0           for my $plugs (
220             $template_plugins , $dir_defaults_plugins, $conf_plugins
221             ) {
222              
223 0           for ( @$plugs ) {
224              
225 0 0         unless ( ref ) {
226 0           $_ = { name => $_, priority => 10000, };
227 0           next;
228             }
229              
230 0 0 0       @{ $_={} }{ qw/name priority/ } = %$_
  0            
231             if ref eq 'HASH' and 1 == keys %$_;
232             }
233             }
234              
235 0           my $r = [
236             map $_->{name},
237             sort {
238 0           $a->{priority}
239             <=>
240             $b->{priority}
241             }
242             $self->uniq_plugins(
243             @$template_plugins,
244             @$dir_defaults_plugins,
245             @$conf_plugins,
246             )
247             ];
248 0           return $r;
249             }
250              
251             sub uniq_plugins {
252 0     0 0   my $self = shift;
253 0           my %h;
254 0 0         return map { $h{ $_->{name} }++ == 0 ? $_ : () } @_;
  0            
255             }
256              
257              
258             sub html_template {
259 0     0 0   my $self = shift;
260 0 0         if ( @_ ) {
261 0           $self->{ html_template } = shift;
262             }
263 0           return $self->{ html_template };
264             }
265              
266              
267             sub template {
268 0     0 0   my $self = shift;
269 0 0         if ( @_ ) {
270 0           $self->{ template } = shift;
271             }
272 0           return $self->{ template };
273             }
274              
275              
276             sub query {
277 0     0 0   my $self = shift;
278 0 0         if ( @_ ) {
279 0           $self->{ query } = shift;
280             }
281 0           return $self->{ query };
282             }
283              
284              
285             sub config {
286 0     0 0   my $self = shift;
287 0 0         if ( @_ ) {
288 0           $self->{ config } = shift;
289             }
290 0           return $self->{ config };
291             }
292              
293              
294             sub conf {
295 0     0 1   my $self = shift;
296 0 0         if ( @_ ) {
297 0           $self->{ conf } = shift;
298             }
299 0           return $self->{ conf };
300             }
301              
302              
303             sub unique_plug_keys {
304 0     0 0   my $self = shift;
305 0 0         if ( @_ ) {
306 0           $self->{UNIQUE_PLUG_KEYS} = shift;
307             }
308 0           return $self->{UNIQUE_PLUG_KEYS};
309             }
310              
311             1;
312             __END__