File Coverage

blib/lib/WebNano/Renderer/TTiny.pm
Criterion Covered Total %
statement 68 70 97.1
branch 21 28 75.0
condition 3 3 100.0
subroutine 7 7 100.0
pod 1 1 100.0
total 100 109 91.7


line stmt bran cond sub pod time code
1             package WebNano::Renderer::TTiny;
2 3     3   23243 use strict;
  3         7  
  3         80  
3 3     3   14 use warnings;
  3         6  
  3         81  
4              
5 3     3   2020 use Template::Tiny;
  3         4082  
  3         104  
6 3     3   687 use Object::Tiny::RW qw/ root _tt_tiny INCLUDE_PATH TEMPLATE_EXTENSION /;
  3         315  
  3         26  
7 3     3   1019 use File::Spec;
  3         4  
  3         1902  
8              
9              
10             sub _to_list {
11 28 100   28   186 if( ref $_[0] ){
    50          
12 12         16 return @{ $_[0] };
  12         40  
13             }
14             elsif( ! defined $_[0] ){
15 0         0 return ();
16             }
17             else{
18 16         41 return $_[0];
19             }
20             }
21              
22             sub render {
23 22     22 1 1279 my( $self, %vars ) = @_;
24 22         40 my $c = $vars{c};
25              
26 22         34 my @search_path;
27 22 50       70 if( $c ){
28 22         38 my $path = ref $c;
29 22         114 $path =~ s/.*::Controller(::)?//;
30 22         40 $path =~ s{::}{/};
31 22         27 @search_path = ( $path, @{ $c->template_search_path });
  22         88  
32             }
33 22 50       269 if( !@search_path ){
34 0         0 @search_path = ( '' );
35             }
36 22         40 my $template = $vars{template};
37 22 100       58 if( !$template ){
38 1         8 my @caller = caller(2);
39 1         2 $template = $caller[3];
40 1         5 $template =~ s/_action$//;
41 1         4 $template =~ s/^.*:://;
42 1 50       26 $template .= '.' . $self->TEMPLATE_EXTENSION if $self->TEMPLATE_EXTENSION;
43             }
44 22         35 my $full_template;
45             LOOP:
46 22         45 for my $path ( @search_path ){
47 33         72 my $to_check;
48 33 100 100     758 if( !$self->root || File::Spec->file_name_is_absolute( $path ) ){
49 6         105 $to_check = File::Spec->catfile( $path, $template );
50 6 100       168 if( -f $to_check ){
51 4         10 $full_template = $to_check;
52 4         12 last LOOP;
53             }
54             }
55             else{
56 27         943 for my $root ( _to_list( $self->root ) ){
57 38         379 $to_check = File::Spec->catfile( $root, $path, $template );
58 38 100       798 if( -f $to_check ){
59 17         26 $full_template = $to_check;
60 17         60 last LOOP;
61             }
62             }
63             }
64             }
65 22         39 my @static_search_path;
66 22 100       57 if( !$full_template ){
67 1         25 @static_search_path = _to_list( $self->INCLUDE_PATH );
68             STATIC_LOOP:
69 1         4 for my $path ( @static_search_path ){
70 1         2 my $to_check;
71 1         10 $to_check = File::Spec->catfile( $path, $template );
72 1 50       18 if( -f $to_check ){
73 1         3 $full_template = $to_check;
74 1         3 last STATIC_LOOP;
75             }
76             }
77             }
78 22 50       51 die "Cannot find $template in search path: @search_path, @static_search_path" if !defined $full_template;
79 22 50       781 open my $fh, $full_template or die "Cannot read from $full_template: $!";
80 22         40 my $string = do { local $/; <$fh> };
  22         76  
  22         520  
81 22 100       564 if( !$self->_tt_tiny ){
82 4         57 $self->_tt_tiny( Template::Tiny->new() );
83             }
84 22         241 my $out;
85 22         474 $self->_tt_tiny->process( \$string, \%vars, \$out );
86 22         2598 return $out;
87             }
88              
89             1;
90              
91              
92              
93             =pod
94              
95             =head1 NAME
96              
97             WebNano::Renderer::TTiny - Dynamic search paths for Template::Tiny
98              
99             =head1 VERSION
100              
101             version 0.001
102              
103             =head1 SYNOPSIS
104              
105             in MyApp.pm:
106              
107             $self->renderer(
108             WebNano::Renderer::TTiny->new( root => 't/data/templates' )
109             );
110              
111             in MyApp::Controller:
112              
113             return $self->render( template => 'some_template.tt', some_var => 'some_value );
114              
115             =head1 DESCRIPTION
116              
117             This is a wrapper around
118             L<Template::Tiny|http://search.cpan.org/~adamk/Template-Tiny/lib/Template/Tiny.pm>
119             - 'Template Toolkit reimplemented in as little code as possible'.
120              
121             The only public method here is render - it expects as input a hash with the
122             following data:
123              
124             =over
125              
126             =item template - the name of the template file
127              
128             =item c - the controller
129              
130             =back
131              
132             The template is then looked for in the directories in C<INCLUDE_PATH> and in
133             directories constructed dynamically from the paths in C<root> and the controller
134             name. For example if 'root' contains C<[ 'template', 'additional_templates' ]>
135             and the controller name is C<MyApp::Controller::SubController> then the template
136             will be looked for in C<template/SubController> and
137             C<additional_templates/SubController>. This mechanism is designed so that it is
138             possible for a way of subclassing templates along with subclassing controllers.
139             If this is too complicated - you can provide no value for the C<root> attribute
140             and use only C<INCLUDE_PATH>.
141              
142             When the template is found - the C<process> method on the internal
143             C<Template::Tiny> object is called. A reference to the whole hash passed to
144             C<render> is passed to the C<process> call - so that all the values are
145             available in the template itself.
146              
147             If no template name is passed - then it is guessed from the name of the
148             controller method that called C<render> (this is done using L<caller>) and the
149             C<TEMPLATE_EXTENSION> attribute.
150              
151             =head1 ATTRIBUTES and METHODS
152              
153             =head2 render
154              
155             =head2 INCLUDE_PATH
156              
157             Static list of template search directories.
158              
159             =head2 root
160              
161             List of directories that are dynamically concatenated with controller names to form
162             a dynamic search list of template directories.
163              
164             You can use INCLUDE_PATH or root or both.
165              
166             =head2 TEMPLATE_EXTENSION
167              
168             Postfix added to action name to form the template name ( for example 'edit.tt'
169             from action 'edit' and TEMPLATE_EXTENSION 'tt' ).
170              
171             =head1 AUTHOR
172              
173             Zbigniew Lukasiak <zby@cpan.org>
174              
175             =head1 COPYRIGHT AND LICENSE
176              
177             This software is copyright (c) 2010 by Zbigniew Lukasiak <zby@cpan.org>.
178              
179             This is free software; you can redistribute it and/or modify it under
180             the same terms as the Perl 5 programming language system itself.
181              
182             =cut
183              
184              
185             __END__
186              
187             # ABSTRACT: Dynamic search paths for Template::Tiny
188