File Coverage

blib/lib/CGI/Application/Plugin/TemplateRunner.pm
Criterion Covered Total %
statement 74 80 92.5
branch 28 38 73.6
condition 1 2 50.0
subroutine 7 7 100.0
pod 4 4 100.0
total 114 131 87.0


line stmt bran cond sub pod time code
1             package CGI::Application::Plugin::TemplateRunner;
2              
3 1     1   23287 use strict;
  1         3  
  1         126  
4 1     1   2105 use HTML::Template;
  1         18554  
  1         53  
5 1     1   12 use base qw(CGI::Application Exporter);
  1         8  
  1         1542  
6              
7              
8              
9             our @EXPORT_OK = qw[
10             show_tmpl
11             prepare_tmpl
12             fill_tmpl
13             ];
14              
15             our $VERSION = '0.04';
16              
17             sub show_tmpl{
18 5     5 1 4584 my ($self) = @_;
19 5         16 my $q = $self->query;
20 5   50     150 my $path = $q->path_info || '/';
21 5 100       1685 $path .= 'index.html' if ($path =~ m{/$} );
22             # we only do .html
23 5 50       28 unless ($path =~ m{\.html$}){
24 0         0 $self->header_add(-status => 404 );
25 0         0 warn "This runmode only serves HTML files (.html), not $path \n";
26 0         0 return;
27             };
28 5         20 my $page = $self->prepare_tmpl($path);
29 5         23 return $page->output;
30             }
31              
32             sub prepare_tmpl{
33 11     11 1 5646 my ($self, $name, %extras) = @_;
34            
35 11         34 my $base = $self->tmpl_path;
36 11 50       111 $base = $base->[0] if ref $base;
37 11 50       27 die "you need to defined a tmpl_path for your application\n" unless $base;
38            
39             # find the template (match _default)
40 11         16 my $filename = $name;
41 11         14 my @defaults;
42 11 100       277 unless (-e "$base/$filename"){
43 3         18 my (@path) = split '/', $filename;
44             # remove trailing /
45 3         6 shift @path;
46 3         8 my $tmp = '';
47 3         11 foreach (@path){
48 6 100       83 if (-e "$base/$tmp/$_"){
49 2         4 $tmp .= "/$_";
50 2         5 next;
51             }
52 4         15 my ($before, $after) = split '\.', $_, 2;
53 4 100       14 $after = defined $after ? ".$after" : '';
54 4 50       139 if (-e "$base/$tmp/_default$after"){
55 4         9 $tmp .= "/_default$after";
56 4         29 push @defaults, $before;
57 4         12 next;
58             }
59 0         0 die "template file $name not found (match so far: $tmp )\n";
60             }
61            
62 3         11 $filename = substr $tmp,1 ; #strip leading slash
63             }
64            
65             # load the template
66 11         18 my $cache = 'cache';
67 11 50       29 $cache = 'shared_cache' if $IPC::SharedCache::VERSION;
68 11         61 my $tmpl = $self->load_tmpl($filename,
69             die_on_bad_params => 0,
70             loop_context_vars => 1,
71             global_vars => 1,
72             $cache => 1,
73             );
74            
75             # TODO: match data file _default independently
76            
77             # load a data file if available
78 11 50       7650 if (-e "$base/$filename.pl"){
79 11         5492 my $result = do "$base/$filename.pl";
80 11 50       194 if ($@){
81 0         0 warn "/$base/$filename.pl could not be compiled: $@ $!\n";
82             }else{
83 11         39 fill_tmpl($self, $tmpl, $result, undef, \@defaults);
84             }
85             }
86            
87             # fill in cookies and params
88 11         49 my $q = $self->query;
89 11         22776 foreach ($q->param){
90 2         42 $tmpl->param("/request/$_" => scalar $q->param($_));
91             }
92 11         569 foreach ($q->cookie){
93 7         2240 $tmpl->param("/cookie/$_" => scalar $q->cookie($_));
94             }
95 11         6992 fill_tmpl($self, $tmpl, $self->{__PARAMS}, '/app');
96              
97             # fill in defaults
98 11         18 my $i = 1;
99 11         26 foreach (@defaults){
100 4         10 $extras{"_defaults/$i"} = $_;
101 4         10 $i++;
102             }
103            
104 11 100       34 fill_tmpl($self, $tmpl, \%extras) if keys %extras;
105 11         46 return $tmpl;
106             }
107              
108             sub fill_tmpl{
109 112     112 1 201 my ($self, $tmpl, $data, $prefix, $defaults) = @_;
110 112 100       274 $prefix = '' unless defined $prefix;
111             # call code refs
112 112 100       233 if (ref $data eq 'CODE'){
113 11 50       17 $data = eval{$data->($self, $defaults ? @$defaults: () )};
  11         42  
114 11 50       212 if ($@){
115 0         0 warn "data sub [$prefix] could not be executed: $@\n";
116             }
117 11         22 fill_tmpl($self, $tmpl, $data, $prefix, $defaults);
118 11         48 return;
119             }
120             # dive into hash refs
121 101 100       202 if (ref $data eq 'HASH'){
122 44         153 while (my ($key, $value) = each %$data){
123 74         205 fill_tmpl($self, $tmpl, $value, "$prefix/$key", $defaults);
124             }
125 44         204 return;
126             }
127             # anything else try to stuff into the template
128 57 100       107 eval { $tmpl->param($prefix => $data);} if defined $data;
  47         140  
129 57 50       1544 warn $@ if $@;
130             }
131              
132             # if used as a base class ( not a plugin)
133             # then set up properly
134             sub setup{
135 4     4 1 6303 my $self = shift;
136 4         14 $self->start_mode('show_tmpl');
137 4         41 $self->run_modes(
138             'show_tmpl' => 'show_tmpl');
139             }
140              
141             1;
142             __END__