File Coverage

blib/lib/Kelp/Module/Template.pm
Criterion Covered Total %
statement 25 25 100.0
branch 8 8 100.0
condition 7 9 77.7
subroutine 7 7 100.0
pod 3 3 100.0
total 50 52 96.1


line stmt bran cond sub pod time code
1             package Kelp::Module::Template;
2              
3 35     35   24344 use Kelp::Base 'Kelp::Module';
  35         76  
  35         245  
4 35     35   18739 use Kelp::Template;
  35         131  
  35         228  
5              
6             attr ext => 'tt';
7             attr engine => sub { die "'engine' must be initialized" };
8              
9             sub build
10             {
11 47     47 1 135 my ($self, %args) = @_;
12              
13             # Build and initialize the engine attribute
14 47         179 $self->engine($self->build_engine(%args));
15              
16             # Register one method - template
17             $self->register(
18             template => sub {
19 79     79   3468 my ($app, $template, $vars, @rest) = @_;
20 79   100     221 $vars //= {};
21 79   33     495 $vars->{app} //= $app;
22              
23 79         317 return $self->render($self->_rename($template), $vars, @rest);
24             }
25 47         419 );
26             }
27              
28             sub build_engine
29             {
30 45     45 1 121 my ($self, %args) = @_;
31 45         311 return Kelp::Template->new(%args);
32             }
33              
34             sub render
35             {
36 75     75 1 165 my ($self, $template, $vars) = @_;
37 75         254 return $self->engine->process($template, $vars);
38             }
39              
40             sub _rename
41             {
42 82     82   202 my ($self, $name) = @_;
43 82   100     205 $name //= '';
44              
45 82 100       274 return $name if ref $name;
46 77 100       203 return undef unless length $name;
47              
48 75   100     241 my $ext = $self->ext // '';
49 75 100       226 return $name unless length $ext;
50              
51 73 100       269 return $name if $name =~ /\./;
52 72         301 return "$name.$ext";
53             }
54              
55             1;
56              
57             __END__
58              
59             =pod
60              
61             =head1 NAME
62              
63             Kelp::Module::Template - Template processing for Kelp applications
64              
65             =head1 SYNOPSIS
66              
67             First ...
68              
69             # conf/config.pl
70             {
71             modules => ['Template'],
72             modules_init => {
73             Template => { ... }
74             }
75             };
76              
77             Then ...
78              
79             # lib/MyApp.pm
80             sub some_route {
81             my $self = shift;
82             $self->template('some_template', { bar => 'foo' });
83             }
84              
85             =head1 DESCRIPTION
86              
87             This module provides an interface for using templates in a Kelp web application. It
88             uses L<Kelp::Template>, but it could be easily subclassed to use anything else.
89              
90             =head1 REGISTERED METHODS
91              
92             =head2 template
93              
94             C<template($filename, \%vars)>
95              
96             Renders a file using the currently loaded template engine. If the file doesn't
97             have an extension, the one specified in L</ext> will be assigned to it.
98              
99             If there is no C<app> in C<%vars>, it will be automatically added.
100              
101             =head1 ATTRIBUTES
102              
103             =head2 ext
104              
105             The default extension of the template files. This module sets this attribute to
106             C<tt>, so
107              
108             $self->template( 'home' );
109              
110             will look for C<home.tt>. Set to undef or empty string to skip adding the
111             extension to filenames.
112              
113             =head2 engine
114              
115             This attribute will be initialized by the C<build_engine> method of this module,
116             and it is available to all code that needs access to the template engine
117             instance. See L</SUBCLASSING> for an example.
118              
119             =head1 METHODS
120              
121             =head2 build_engine
122              
123             C<build_engine(%args)>
124              
125             This method is responsible for creating, initializing and returning an instance
126             of the template engine used, for example L<Template>. Override it to use a
127             different template engine, for example L<Text::Haml>.
128              
129             =head2 render
130              
131             C<render($template, \%vars, @rest)>
132              
133             This method should return a rendered text. Override it if you're subclassing and
134             using a different template engine.
135              
136             =head1 PERKS
137              
138             =head2 UTF8
139              
140             To process templates in utf8, add the C<encoding> to the module configuration:
141              
142             # conf/config.pl
143             {
144             modules => ['Template'],
145             modules_init => {
146             Template => {
147             encoding => 'utf8'
148             }
149             }
150             };
151              
152             =head1 SUBCLASSING
153              
154             To use a different template engine, you can subclass this module. You will need
155             to make sure your new class does the following (for the sake of the example we
156             will show you how to create a L<Text::Haml> rendering module):
157              
158             =over
159              
160             =item
161              
162             Overrides the L</ext> attribute and provides the file extension of the new
163             template files.
164              
165             attr ext => 'haml';
166              
167             =item
168              
169             Overrides the L</build_engine> method and creates an instance of the new
170             template engine.
171              
172             sub build_engine {
173             my ( $self, %args ) = @_;
174             return Text::Haml->new( %args );
175             }
176              
177             =item
178              
179             Overrides the L</render> method and renders using C<$self-E<gt>engine>.
180              
181             sub render {
182             my ( $self, $template, $vars, @rest ) = @_;
183              
184             # Get the template engine instance
185             my $haml = $self->engine;
186              
187             # If the $template is a reference, then render string,
188             # otherwise it's a file name.
189             return ref($template) eq 'SCALAR'
190             ? $haml->render( $$template, %$vars )
191             : $haml->render_file( $template, %$vars );
192             }
193              
194             =back
195              
196             =cut
197