File Coverage

blib/lib/Mojolicious/Plugin/HandlebarsJSRenderer.pm
Criterion Covered Total %
statement 15 17 88.2
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 21 23 91.3


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::HandlebarsJSRenderer;
2              
3 1     1   20836 use 5.006;
  1         4  
4 1     1   4 use strict;
  1         2  
  1         26  
5 1     1   5 use warnings;
  1         6  
  1         42  
6              
7 1     1   765 use Mojo::Base 'Mojolicious::Plugin';
  1         11608  
  1         6  
8 1     1   2092 use Mojo::Util qw/slurp dumper/;
  1         105372  
  1         220  
9              
10 1     1   500 use JavaScript::V8::Handlebars;
  0            
  0            
11              
12             our $VERSION = '0.05';
13              
14             has 'wrapper';
15              
16             sub register {
17             my( $self, $app, $conf ) = @_;
18             my $hbjs = JavaScript::V8::Handlebars->new;
19              
20             #TODO Clean this up
21             if( $conf->{wrapper} ) {
22             for( @{ $app->renderer->paths } ) {
23             if( -r "$_/$conf->{wrapper}" ) {
24             $self->wrapper( "$_/$conf->{wrapper}" );
25             last;
26             }
27             }
28              
29             if( $self->wrapper ) {
30             $self->wrapper( $hbjs->compile_file( $self->wrapper ) );
31             }
32             else {
33             die "Failed to find/read $conf->{wrapper} in @{$app->renderer->paths}";
34             }
35             }
36              
37             if( $conf->{helpers} ) {
38              
39             my $helper_path;
40             for( @{ $app->renderer->paths } ) {
41             if( -r "$_/$conf->{helpers}" ) {
42             $helper_path = "$_/$conf->{helpers}";
43             last;
44             }
45             }
46              
47             die unless $helper_path;
48              
49             $hbjs->eval_file($helper_path);
50             }
51              
52             for( @{ $app->renderer->paths } ) {
53             next unless -d $_;
54             # Magically picks up partials as well
55             $hbjs->add_template_dir( $_ );
56             }
57              
58              
59             $app->renderer->add_handler( hbs => sub {
60             my( $r, $c, $output, $options ) = @_;
61              
62             return unless $r->template_path($options) or length $options->{inline};
63              
64             if( length $options->{inline} ) {
65             $$output = $hbjs->render_string( $options->{inline}, $c->stash );
66             }
67             elsif( my $template = $r->template_for($c) ) {
68             $$output = $hbjs->execute_template( $template, $c->stash );
69             }
70             else {
71             #TODO should this die?
72             return;
73             }
74              
75             if( $self->wrapper ) {
76             $$output = $self->wrapper->({ %{$c->stash}, content => $$output });
77             }
78              
79             return 1;
80             } );
81             }
82              
83              
84              
85             =head1 NAME
86              
87             Mojolicious::Plugin::HandlebarsJSRenderer - Render Handlebars inside Mojolicious
88              
89             =head1 SYNOPSIS
90              
91             This is a plugin for adding the Handlebars templating language to Mojolicious as a renderer.
92              
93             sub startup {
94             my $self = shift;
95             ...
96              
97             $self->plugin('HandlebarsJSRenderer', { [wrapper => "wrapper.hbs"], [helpers => "helpers.js"] });
98             $self->renderer->default_handler('hbs') #default to hbs templates instead of epl
99             ...
100             }
101              
102             Note that by default when this plugin is initialized it attempts to cache every .hbs file inside your templates directory, which includes registering any files under a directory named 'partials' as a partial with the same name as the file. You can also pass a wrapper file which is executed after any render call and passed the results of the first render as the variable 'content'. Specifying a helpers.js file allow you to execute Handlebars.registerHelper() statements to provide functions to your templates. Or really, any other code you want.
103              
104              
105             =head1 AUTHOR
106              
107             Robert Grimes, C<< >>
108              
109             =head1 BUGS
110              
111             Please report any bugs or feature requests to C, or through
112             the web interface at L. I will be notified, and then you'll
113             automatically be notified of progress on your bug as I make changes.
114              
115              
116              
117              
118             =head1 SUPPORT
119              
120             You can find documentation for this module with the perldoc command.
121              
122             perldoc Mojolicious::Plugin::HandlebarsJSRenderer
123              
124              
125             You can also look for information at:
126              
127             =over 4
128              
129             =item * RT: CPAN's request tracker (report bugs here)
130              
131             L
132              
133             =item * AnnoCPAN: Annotated CPAN documentation
134              
135             L
136              
137             =item * CPAN Ratings
138              
139             L
140              
141             =item * Search CPAN
142              
143             L
144              
145             =back
146              
147              
148             =head1 ACKNOWLEDGEMENTS
149              
150              
151             =head1 LICENSE AND COPYRIGHT
152              
153             Copyright 2015 Robert Grimes.
154              
155             This program is free software; you can redistribute it and/or modify it
156             under the terms of the the Artistic License (2.0). You may obtain a
157             copy of the full license at:
158              
159             L
160              
161             Any use, modification, and distribution of the Standard or Modified
162             Versions is governed by this Artistic License. By using, modifying or
163             distributing the Package, you accept this license. Do not use, modify,
164             or distribute the Package, if you do not accept this license.
165              
166             If your Modified Version has been derived from a Modified Version made
167             by someone other than you, you are nevertheless required to ensure that
168             your Modified Version complies with the requirements of this license.
169              
170             This license does not grant you the right to use any trademark, service
171             mark, tradename, or logo of the Copyright Holder.
172              
173             This license includes the non-exclusive, worldwide, free-of-charge
174             patent license to make, have made, use, offer to sell, sell, import and
175             otherwise transfer the Package with respect to any patent claims
176             licensable by the Copyright Holder that are necessarily infringed by the
177             Package. If you institute patent litigation (including a cross-claim or
178             counterclaim) against any party alleging that the Package constitutes
179             direct or contributory patent infringement, then this Artistic License
180             to you shall terminate on the date that such litigation is filed.
181              
182             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
183             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
184             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
185             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
186             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
187             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
188             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
189             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
190              
191              
192             =cut
193              
194             1; # End of Mojolicious::Plugin::HandlebarsJSRenderer