File Coverage

blib/lib/Maypole/View/TT.pm
Criterion Covered Total %
statement 3 3 100.0
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 4 4 100.0


line stmt bran cond sub pod time code
1             package Maypole::View::TT;
2 1     1   5275 use base 'Maypole::View::Base';
  1         1  
  1         168  
3             use Maypole::Constants;
4             use Template;
5             use File::Spec::Functions qw(catdir tmpdir);
6             use Template::Constants qw( :all );
7              
8             our $error_template;
9             { local $/; $error_template = ; }
10              
11             our $VERSION = '2.12';
12              
13             my $debug_flags = DEBUG_ON;
14              
15             use strict;
16              
17             sub template {
18             my ( $self, $r ) = @_;
19             unless ($self->{tt}) {
20             my $view_options = $r->config->view_options || {};
21             if ($r->debug) {
22             $view_options->{DEBUG} = $debug_flags;
23             }
24              
25             $view_options->{POST_CHOMP} = 1 unless (exists $view_options->{POST_CHOMP});
26             $self->{provider} = Template::Provider->new($view_options);
27             $self->{tt} = Template->new({
28             %$view_options,
29             LOAD_TEMPLATES => [ $self->{provider} ],
30             });
31             }
32              
33             $self->{provider}->include_path([ $self->paths($r) ]);
34              
35             my $template_file = $r->template;
36              
37             my $ext = $r->config->template_extension;
38             $template_file .= $ext if defined $ext;
39              
40             my $output;
41             my $processed_ok = eval{$self->{tt}->process($template_file, { $self->vars($r) }, \$output );};
42             if ($processed_ok) {
43             $r->{output} = $output;
44             return OK;
45             } else {
46             if ($@) {
47             my $error = "fatal error in template '$template_file' : $@\nTT paths : " . join(', ',$self->paths($r)) . "\n";
48             $r->warn($error);
49             $r->{error} = $error;
50             } else {
51             my $error = "TT error for template '$template_file'\n" . $self->{tt}->error . "\nTT paths : " . join(', ',$self->paths($r)) . "\n";
52             $r->warn($error);
53             $r->{error} = $error;
54             }
55             return ERROR;
56             }
57             }
58              
59              
60             sub report_error {
61             my ($self, $r, $error, $type) = @_;
62             my $output;
63              
64             # Need to be very careful here.
65             my $tt = Template->new;
66             unless (ref $r->{config}) {
67             $r->warn("no config for this request");
68             $error .= '
There was a problem finding configuration for this request';
69             $r->{config} ||= {};
70             }
71              
72             $r->warn("report_error - reporting error to user : $error\n");
73              
74             if ($tt->process(\$error_template,
75             { err_type => $type, error => $error,
76             config => $r->{config},
77             request => $r,
78             paths => [ $self->paths($r) ],
79             eval{$self->vars($r)} }, \$output )) {
80             $r->{output} = $output;
81             if ($tt->error) { $r->{output} = "Even the error template
82             errored - ".$tt->error.""; }
83             $r->{content_type} ||= "text/html";
84             $r->{document_encoding} ||= "utf-8";
85             return OK;
86             }
87             return ERROR;
88             }
89              
90              
91             =head1 NAME
92              
93             Maypole::View::TT - A Template Toolkit view class for Maypole
94              
95             =head1 SYNOPSIS
96              
97             BeerDB->config->view("Maypole::View::TT"); # The default anyway
98              
99             # Set some Template Toolkit options
100             BeerDB->config->view_options( {
101             TRIM => 1,
102             COMPILE_DIR => '/var/tmp/mysite/templates',
103             } );
104              
105             .....
106              
107             [% PROCESS macros %]
108              
109             [% pager %]
110              
111             [% link %]
112              
113             [% maybe_link_view %]
114              
115             =head1 DESCRIPTION
116              
117             This is the default view class for Maypole; it uses the Template Toolkit to fill
118             in templates with the objects produced by Maypole's model classes. Please see
119             the L, and in particular, the
120             L chapter for the template variables available and
121             for a refresher on how template components are resolved.
122              
123             The underlying Template toolkit object is configured through
124             C<$r-Econfig-Eview_options>. See L for available
125             options.
126              
127             =over 4
128              
129             =item template
130              
131             Processes the template and sets the output. See L
132              
133             =item report_error
134              
135             Reports the details of an error, current state and parameters
136              
137             =back
138              
139             =head1 TEMPLATE TOOLKIT INTRODUCTION
140              
141             The Template Toolkit uses it's own mini language described in
142             L.
143              
144             A simple example would be :
145              
146             =over 4
147              
148             re:[% subject %]
149              
150             Dear [% title %] [% surname %],
151             Thank you for your letter dated [% your.date %]. This is to
152             confirm that we have received it and will respond with a more
153             detailed response as soon as possible. In the mean time, we
154             enclose more details of ...
155              
156             =back
157              
158             TT uses '[%' and '%]' (by default) to delimit directives within a template, and
159             the simple directives above just display the value of variable named within
160             those delimiters -- [% title %] will be replaced inline with the value of the
161             'title' variable passed in the 'stash' to the template when it is processed.
162              
163             You can access nested data through the dot ('.') operator, which will
164             dereference array or hash elements, but can also be used to call methods on
165             objects, i.e. '[% name.salutation("Dear %s,") %]'. The other main operator is
166             underscore ('_'), which will concatonate strings or variables.
167              
168             The value returned by a directive replaces the directive inline when the
169             template is processes, you can also SET a value which will not return anything,
170             or CALL a method or operation which will also not return anything.
171              
172             You can specify expressions using the logical (and, or, not, ?:) and mathematic
173             operators (+ - * / % mod div).
174              
175             Results of TT commands are interpolated in the place of the template tags, unless
176             using SET or CALL, i.e. [% SET foo = 1 %], [% GET foo.bar('quz'); %]
177              
178             =over 4
179              
180             [% template.title or default.title %]
181              
182             [% score * 100 %]
183              
184             [% order.nitems ? checkout(order.total) : 'no items' %]
185              
186             =back
187              
188             TT allows you to include or re-use templates through it's INCLUDE, PROCESS and
189             INSERT directives, which are fairly self explainatory. You can also re-use parts
190             of template with the BLOCK or MACRO directives.
191              
192             Conditional and Looping constructs are simple and powerful, and TT provides an
193             inbuilt iterator and helper functions and classes that make life sweet.
194              
195             Conditional directives are IF, UNLESS, ELSIF, ELSE and behave as they would in
196             perl :
197              
198             =over 4
199              
200             [% IF age < 10 %]
201             Hello [% name %], does your mother know you're using her AOL account?
202             [% ELSIF age < 18 %]
203             Sorry, you're not old enough to enter (and too dumb to lie about your age)
204             [% ELSE %]
205             Welcome [% name %].
206             [% END %]
207              
208             [% UNLESS text_mode %] [% INCLUDE biglogo %] [% END %]
209              
210             =back
211              
212             Looping directives are FOREACH, LAST and BREAK.
213              
214             FOREACH loops through a HASH or ARRAY processing the enclosed block for each
215             element.
216              
217             Looping through an array
218              
219             [% FOREACH i = items %]
220             [% i %]
221             [% END %]
222              
223             Looping through a hash
224              
225             [% FOREACH u IN users %]
226             * [% u.key %] : [% u.value %]
227             [% END %]
228              
229             Looping through an array of hashes
230              
231             [% FOREACH user IN userlist %]
232             * [% user.id %] [% user.name %]
233             [% END %]
234              
235             The LAST and BREAK directive can be used to exit the loop.
236              
237             The FOREACH directive is implemented using the Template::Iterator module. A
238             reference to the iterator object for a FOREACH directive is implicitly available
239             in the 'loop' variable. The loop iterator object provides a selection of methods
240             including size(), max(), first(), last(), count(), etc
241              
242             =over 4
243              
244             [% FOREACH item IN [ 'foo', 'bar', 'baz' ] -%]
245             [%- "
    \n" IF loop.first %]
246            
  • [% loop.count %]/[% loop.size %]: [% item %]
  • 247             [%- "\n" IF loop.last %]
    248             [% END %]
    249              
    250             =back
    251              
    252             See Template::Iterator for further details on looping and the Iterator.
    253              
    254             You might notice the minus ('-') operator in the example above, it is used to
    255             remove a newline before or after a directive so that you can layout the Template
    256             logic as above but the resulting output will look exactly how you require it.
    257              
    258             You will also frequently see comments and multi-line directives, # at the start
    259             of a directive marks it as a comment, i.e. '[%# this is a comment %]'. A
    260             multiline directive looks like :
    261              
    262             [% do.this;
    263             do.that;
    264             do.the_other %]
    265              
    266             You can see that lines are terminated with a semi-colon (';') unless the
    267             delimter ('%]') closes the directive.
    268              
    269             For full details of the Template Toolkit see Template::Manual and
    270             Template::Manual::Directives, you can also check the website, mailing list or
    271             the Template Toolkit book published by O Reilly.
    272              
    273             =head1 TEMPLATE PLUGINS, FILTERS AND MACROS
    274              
    275             The Template Toolkit has a popular and powerful selection of Plugins and
    276             Filters.
    277              
    278             TT Plugins provide additional functionality within Templates, from accessing CGI
    279             and databases directly, handling paging or simple integration with Class::DBI
    280             (for those rare occasions where you don't actually need Maypole). See
    281             L.
    282              
    283             One plugin that is indispensible when using Maypole and the Template View is
    284             C -- This allows you to import and use any class
    285             installed within a template. For example :
    286              
    287             =over 4
    288              
    289             [% USE foo = Class('Foo') %]
    290             [% foo.bar %]
    291              
    292             =back
    293              
    294             Would do the equivilent of 'use Foo; Foo->bar;' in perl. See
    295             L for details.
    296              
    297             TT Filters process strings or blocks within a template, allowing you to
    298             truncate, format, escape or encode trivially. A useful selection is included
    299             with Template Toolkit and they can also be found on CPAN or can be written
    300             easily. See L.
    301              
    302             TT provides stderr and stdout filters, which allow you to write handy macros
    303             like this one to output debug information to your web server log, etc :
    304              
    305             =over 4
    306              
    307             [% MACRO debug_msg(text)
    308             FILTER stderr; "[TT debug_msg] $text\n"; END;
    309             %]
    310              
    311             =back
    312              
    313              
    314             TT Macros allow you to reuse small blocks of content, directives, etc. The MACRO
    315             directive allows you to define a directive or directive block which is then
    316             evaluated each time the macro is called. Macros can be passed named parameters
    317             when called.
    318              
    319             Once a MACRO is defined within a template or 'include'd template it can be used
    320             as if it were a native TT directive. Maypole provides a selection of powerful
    321             and useful macros in the templates/ directory of the package and these are used
    322             in the beerdb and default templates. See the MACRO section of the
    323             L documentation.
    324              
    325             =head1 ACCESSING MAYPOLE VALUES
    326              
    327             =head2 request
    328              
    329             You can access the request in your templates in order to see the action, table, etc as well
    330             as parameters passed through forms :
    331              
    332             for example
    333              
    334             Hello [% request.params.forename %] [% request.params.surname %] !
    335              
    336             or
    337              
    338             Are you want to [% request.action %] in the [% request.table %] ?
    339              
    340             =head2 config
    341              
    342             You can access your maypole application configuration through the config variable :
    343              
    344            
    345              
    346             =head2 object and objects
    347              
    348             Objects are passed to the request using r->objects($arrayref) and are accessed in the templates
    349             as an array called objects.
    350              
    351             [% FOR objects %] [% object %] [% END %]
    352              
    353             =head1 MAYPOLE MACROS AND FILTERS
    354              
    355             Maypole provides a collection of useful and powerful macros in the templates/factory/macros
    356             and other templates. These can be used in any template with [% PROCESS templatename %].
    357              
    358             =head2 link
    359              
    360             This creates an to a command in the Apache::MVC system by
    361             catenating the base URL, table, command, and any arguments.
    362              
    363             =head2 maybe_link_view
    364              
    365             C takes something returned from the database - either
    366             some ordinary data, or an object in a related class expanded by a
    367             has-a relationship. If it is an object, it constructs a link to the view
    368             command for that object. Otherwise, it just displays the data.
    369              
    370             =head2 pager
    371              
    372             This is an include template rather than a macro, and it controls the pager
    373             display at the bottom (by default) of the factory list and search views/template.
    374             It expects a C template argument which responds to the L interface.
    375              
    376             This macro is in the pager template and used as :
    377              
    378             [% PROCESS pager %]
    379              
    380             Maypole provides a pager for list and search actions, otherwise you can
    381             provide a pager in the template using Template::Plugin::Pagination.
    382              
    383             [% USE pager = Pagination(objects, page.current, page.rows) %]
    384             ...
    385             [% PROCESS pager %]
    386              
    387             The pager will use a the request action as the action in the url unless the
    388             pager_action variable is set, which it will use instead if available.
    389              
    390             =head2 other macros
    391              
    392             =head1 AUTHOR
    393              
    394             Simon Cozens
    395              
    396             =cut
    397              
    398             1;
    399              
    400             __DATA__