File Coverage

lib/PSGI/Hector/Response/TemplateToolkit.pm
Criterion Covered Total %
statement 48 84 57.1
branch 8 24 33.3
condition 3 9 33.3
subroutine 10 16 62.5
pod 6 7 85.7
total 75 140 53.5


line stmt bran cond sub pod time code
1             #response object
2             package PSGI::Hector::Response::TemplateToolkit;
3              
4             =pod
5              
6             =head1 NAME
7              
8             Response TemplateToolkit - View plugin using template toolkit
9              
10             =head1 SYNOPSIS
11              
12             my $response = $hector->getResponse();
13             $response->setTemplateVar("hello", $something);
14              
15             =head1 DESCRIPTION
16              
17             This view plugin allows you to read a template file and replace placholders with scalar variables.
18              
19             With this class you can specify empty Hector actions to just display a static page.
20              
21             The display() can additionally be called by a controller action multiple times if several different templates need to be output.
22              
23             =head1 METHODS
24              
25             =cut
26              
27 2     2   1063 use strict;
  2         5  
  2         46  
28 2     2   7 use warnings;
  2         3  
  2         37  
29 2     2   907 use Template;
  2         31445  
  2         52  
30 2     2   11 use Carp;
  2         5  
  2         103  
31 2     2   10 use parent qw(PSGI::Hector::Response::Base);
  2         4  
  2         15  
32             our $templateLoc = "root/templates"; #where the templates are stored
33             #########################################################
34              
35             =head2 new($hector)
36              
37             Constructor, All environment hash is saved in template variable "env" and the current action is saved as "action" so they can be accessed
38             along with any other variables stored during the server action in the usual template toolkit way.
39              
40             =cut
41              
42             #########################################################
43             sub new{
44 1     1 1 4 my($class, $hector) = @_;
45 1         5 my $self = $class->SUPER::new($hector);
46 1         2 $self->{'_template'} = undef;
47 1         3 $self->{'_templateVars'} = {};
48 1         1 bless $self, $class;
49 1         4 $self->setTemplateVar("env", $hector->getEnv()); #include this var by default
50 1         3 $self->setTemplateVar("hector", $hector); #this will be handy to have too
51 1         4 $self->setTemplateVar("action", $hector->getAction()); #this will be handy to have too
52 1         4 $self->setTemplateVar("debug", $hector->getOption("debug"));
53 1         2 return $self;
54             }
55             #########################################################
56              
57             =head2 setTemplate($template)
58              
59             $response->setTemplate("login");
60              
61             Manually set the template to display.
62              
63             An file extension of '.html' will be automatically appended to this name.
64              
65             The template will be fetched from the template directory, See the L
66             section for more details.
67              
68             =cut
69              
70             #########################################################
71             sub setTemplate{
72 1     1 1 6 my($self, $template) = @_;
73 1         2 $self->{'_template'} = $template;
74 1         4 return 1;
75             }
76             #########################################################
77             sub getTemplate{
78 4     4 0 124 my $self = shift;
79 4         11 return $self->{'_template'};
80             }
81             #########################################################
82              
83             =pod
84              
85             =head2 display()
86              
87             $response->display();
88              
89             This method is called automatically at the end of an action.
90              
91             A template is automatically chosen. An example demonstrates how this is done.
92              
93             URL used: /foo/bar/app.cgi?action=login
94             Template chosen: app-login.html
95              
96             =cut
97              
98             #########################################################
99             sub display{ #this sub will display the page headers if needed
100 2     2 1 861 my $self = shift;
101 2 50       4 if(!$self->getTemplate()){ #if no template has been set in the action sub then we set a default
102 0         0 my $tName = $self->_getTemplateNameForAction();
103 0         0 $self->setTemplate($tName); #set the template automatically
104             }
105 2 50 33     11 if(!$self->getError() && !$self->header("Location") && !$self->getTemplate()){ #we must have a template set if we dont have an error or a redirect
      33        
106 0         0 $self->setError("No template defined");
107             }
108 2 100       9 if($self->_getDisplayedHeader()){ #just display more content
109 1         3 my $content = $self->_getContent(); #get the contents of the template
110 1         5 $self->add_content_utf8($content);
111             }
112             else{ #first output so display any headers
113 1 50       13 if($self->header("Location")){
114 0         0 $self->code(302);
115 0         0 $self->message('Found');
116             }
117             else{ #if we dont have a redirect
118 1 50       38 if(!$self->header("Content-Type")){ #set default content type
119 1         34 $self->header("Content-Type" => "text/html");
120             }
121 1         43 my $content = $self->_getContent(); #get the contents of the template
122 1         8 $self->add_content_utf8($content);
123             }
124 1 50 33     31 if($self->getError() && $self->code() =~ m/^[123]/){ #set the error code when needed
125 0         0 $self->code(500);
126 0         0 $self->message('Internal Server Error');
127             }
128 1         5 $self->_setDisplayedHeader(); #we wont display the header again
129             }
130 2 50       24 if($self->getError()){
131 0         0 $self->getHector()->getLog()->log($self->getError(), 'error'); #just log it so we have a record of this
132             }
133 2         8 return $self->SUPER::display();
134             }
135             #########################################################
136              
137             =pod
138              
139             =head2 setError($message)
140              
141             $response->setError("something has broken");
142              
143             Set an error message for the response, which is accessible in the error template
144             as [% message %].
145              
146             =cut
147              
148             #########################################################
149             sub setError(){
150 0     0 1 0 my($self, $message) = @_;
151 0         0 $self->setTemplateVar("message", $message); #so we can access the error message via smarty
152 0         0 return $self->SUPER::setError($message); #save the message for later in the instance
153             }
154             #########################################################
155              
156             =pod
157              
158             =head2 setTemplateVar($name, $value)
159              
160             $response->setTemplatevar("name", "Bob");
161              
162             Creates a template variable with the specified name and value.
163             The variable may be of any type and can be access from the template in the
164             usual way.
165              
166             =cut
167              
168             #########################################################
169             sub setTemplateVar{
170 4     4 1 6 my($self, $name, $value) = @_;
171 4         7 $self->{'_templateVars'}->{$name} = $value;
172 4         4 return 1;
173             }
174             #########################################################
175              
176             =pod
177              
178             =head2 getTemplateVar($name)
179              
180             $response->getTemplateVar("name");
181              
182             Returns the value of the given template variable.
183              
184             =cut
185              
186             #########################################################
187             sub getTemplateVar{
188 0     0 1   my($self, $name) = @_;
189 0           my $vars = $self->_getTemplateVars();
190 0           return $vars->{$name};
191             }
192             #########################################################
193             # private methods
194             ########################################################
195             sub _getTemplateVars{
196 0     0     my $self = shift;
197 0           return $self->{'_templateVars'};
198             }
199             #########################################################
200             sub _getContent{
201 0     0     my $self = shift;
202 0           my $content = "";
203 0           my $tt = Template->new(
204             {
205             INCLUDE_PATH => $self->_getTemplatePath(),
206             ENCODING => 'utf-8'
207             }
208             );
209 0 0         if($tt){
210 0 0         if(!$self->getError()){
211 0           my $result = $tt->process($self->getTemplate() . ".html", $self->_getTemplateVars(), \$content);
212 0 0         unless($result){
213 0           $self->setError($tt->error());
214             }
215             }
216             }
217             else{
218 0           $self->setError($Template::ERROR);
219             }
220 0 0         if($self->getError()){ #_parseFile may have errored
221 0           my $result = $tt->process("genericerror.html", $self->_getTemplateVars(), \$content);
222 0 0         unless($result){
223 0           $self->getHector()->getLog()->log($tt->error(), 'error');
224             }
225             }
226 0           return $content;
227             }
228             ###########################################################
229             sub _getTemplateNameForAction{
230 0     0     my $self = shift;
231 0           my $hector = $self->getHector();
232 0           my $action = $hector->getAction();
233 0           $action =~ s/ /_/g; #remove spaces in action if any
234 0           return $action;
235             }
236             #########################################################
237             sub _getTemplatePath{
238 0     0     $templateLoc;
239             }
240             ##############################################################
241              
242             =pod
243              
244             =head1 Notes
245              
246             If an error occurs a template called "genericerror.html" will be used instead of the specified template.
247             Please make sure you have this file, there is an example of this in the "root/templates" directory of this module.
248              
249             To change the template location use the following code at the top of your script:
250              
251             $PSGI::Hector::Response::SimpleTemplate::templateLoc = "../root";
252              
253             =head1 See also
254              
255             L