File Coverage

blib/lib/Plosurin.pm
Criterion Covered Total %
statement 103 109 94.5
branch 10 20 50.0
condition 5 14 35.7
subroutine 32 35 91.4
pod 1 3 33.3
total 151 181 83.4


line stmt bran cond sub pod time code
1             #===============================================================================
2             #
3             # DESCRIPTION: Plosurin - Perl 5 implementation of Closure Templates
4             #
5             # AUTHOR: Aliaksandr P. Zahatski, <zahatski@gmail.com>
6             #===============================================================================
7             package Plosurin;
8              
9             =head1 NAME
10              
11             Plosurin - Perl 5 implementation of Closure Templates
12              
13             =head1 SYNOPSIS
14              
15             For template C<example.soy> with content:
16              
17             {namespace mytest}
18            
19             /**
20             * Simple test
21             */
22             {template .Hello}
23             <h1>Foreach example</h1>
24             {foreach $a in [1,2]}
25             <p>Line: {$a}</p><br/>
26             {/foreach}
27             <p>Ok</p>
28             {/template}
29              
30             To get Perl 5 module (MyApp, for example), just run the following command:
31              
32             plosurin.p5 -package MyApp < example.soy > MyApp.pm
33              
34             Use template in your Perl 5 program:
35              
36             use MyApp;
37             print &MyApp::mytest_Hello();
38              
39             or get help:
40              
41             perldoc MyApp.pm
42              
43             =head1 DESCRIPTION
44              
45             Plosurin - Perl implementation of Closure Templates.
46              
47             =head2 Template Structure
48              
49             Every Soy file should have these components, in this order:
50              
51             =over
52              
53             =item * A namespace declaration.
54              
55             =item * One or more template definitions.
56              
57             =back
58              
59             Here is an example template:
60              
61             {namespace examples.simple}
62             /**
63             * Says hello to a person.
64             * @param name The name of the person to say hello to.
65             */
66             {template .helloName}
67             Hello {$name}!
68             {/template}
69              
70              
71             =head2 Command Syntax
72              
73             Commands are instructions that you give the template compiler to create templates and add custom logic to templates. Put commands within Closure Template tags, which are delimited by braces (C<{}>).
74              
75             The first token within a tag is the command name (the print command is implied if no command is specified), and the rest of the text within the tag (if any) is referred to as the command text. Within the template you can enclose other commands to evaluate conditional expressions, iterate over data objects, or print messages.
76              
77             {/foreach}
78             {if length($items) > 5}
79             {msg desc="Says hello to the user."}
80              
81             If a command has a corresponding end command, then the end command's name is a C</> followed by the name of the start command, e.g. foreach and C</foreach>.
82              
83             =cut
84              
85             package Plo::File;
86 2     2   126792 use Plosurin::SoyTree;
  2         6  
  2         91  
87 2     2   15 use base 'Soy::base';
  2         6  
  2         1059  
88             our $VERSION = '0.01';
89              
90             sub new {
91 6     6   17 my $class = shift;
92 6 50 33     42 my $self = bless( ( $#_ == 0 ) ? shift : {@_}, ref($class) || $class );
93              
94             #set namespace
95 6         24 my $namespace = $self->{namespace}->{id};
96              
97             #set src file
98 6         15 my $file = $self->{file};
99 6         10 foreach my $tmpl ( @{ $self->{templates} } ) {
  6         21  
100 12         25 $tmpl->{namespace} = $namespace;
101 12         28 $tmpl->{srcfile} = $file;
102             }
103              
104 6         121 $self;
105             }
106              
107             sub namespace {
108 7     7   19 $_[0]->{namespace}->{id};
109             }
110              
111             sub childs {
112 1     1   3 my $self = shift;
113 1         3 return [ $self->templates ];
114             }
115              
116             =head2 templates
117              
118             Return array of tempaltes
119              
120             =cut
121              
122             sub templates {
123 6     6   22 my $self = shift;
124 6         10 @{ $self->{templates} };
  6         35  
125             }
126              
127             package Plo::template;
128 2     2   18 use strict;
  2         4  
  2         45  
129 2     2   12 use warnings;
  2         5  
  2         57  
130 2     2   11 use Plosurin::SoyTree;
  2         4  
  2         52  
131 2     2   11 use base 'Soy::base';
  2         5  
  2         1425  
132             our $VERSION = '0.01';
133              
134             sub new {
135 12     12   26 my $class = shift;
136 12 50 33     255 bless( ( $#_ == 0 ) ? shift : {@_}, ref($class) || $class );
137             }
138              
139 2     2   15 sub body { $_[0]->{template_block}->{raw_template} }
140 8     8   30 sub name { $_[0]->{template_block}->{start_template}->{name} }
141              
142             sub comment {
143 3     3   5 return join "\n", map { $_->{raw_str} } @{ $_[0]->{header}->{h_comment} };
  5         37  
  3         9  
144             }
145 3 50   3   12 sub params { exists $_[0]->{header}->{h_params} ? @{ $_[0]->{header}->{h_params} } : ()}
  3         15  
146 1     1   3 sub full_name { my $self = shift; $self->{namespace} . $self->name }
  1         4  
147              
148             sub namespace {
149 0     0   0 $_[0]->{namespace}->{id};
150             }
151              
152             #parse body and return Soy tree
153             sub childs {
154 2     2   7 my $self = shift;
155             my $plo = new Plosurin::SoyTree(
156             src => $self->body,
157             offset => $self->{template_block}->{matchline},
158             srcfile => $self->{srcfile}
159 2         7 );
160 2 50       7 die $plo unless ref $plo;
161              
162 2         7 my $reduced = $plo->reduced_tree;
163 2         10 return $reduced;
164             }
165              
166             1;
167              
168             package Plo::h_params;
169             our $VERSION = '0.01';
170              
171             sub new {
172 15     15   33 my $class = shift;
173 15 50 33     299 bless ( ($#_ == 0) ? shift : {@_}, ref($class) || $class);
174             }
175              
176 4     4   15 sub name { $_[0]->{id} }
177 0     0   0 sub is_notreq {$_[0]->{is_notreq} }
178 0     0   0 sub comment {$_[0]->{raw_str}}
179              
180             1;
181              
182             package Plosurin;
183              
184             =head1 Perl 5 code generator API
185              
186             use Plosurin;
187             my $p = new Plosurin::;
188             my $in_fd = new IO::File:: "< $infile" or die "$infile: $!";
189             my $nodes = $p->parse( $in, "file_name.soy");
190             say $p->as_perl5( { package => "MyApp::Templates" }, $nodes );
191              
192              
193             =cut
194              
195 2     2   52 use strict;
  2         5  
  2         57  
196 2     2   11 use warnings;
  2         4  
  2         67  
197 2     2   20 use v5.10;
  2         8  
198             our $VERSION = '0.2';
199 2     2   14 use Regexp::Grammars;
  2         5  
  2         84  
200 2     2   378 use Plosurin::Grammar;
  2         6  
  2         76  
201 2     2   483 use Plosurin::Context;
  2         6  
  2         49  
202 2     2   10 use Plosurin::SoyTree;
  2         9  
  2         35  
203 2     2   445 use Plosurin::To::Perl5;
  2         6  
  2         60  
204 2     2   464 use Plosurin::Writer::Perl5;
  2         5  
  2         241  
205             our $file = "???";
206              
207             sub new {
208 3     3 0 276 my $class = shift;
209 3 50 33     36 bless( ( $#_ == 0 ) ? shift : {@_}, ref($class) || $class );
210             }
211              
212             sub parse {
213 6     6 0 25 my $self = shift;
214 6         13 my $ref = shift;
215 6         10 our $file = shift;
216 6         43 my $r = qr{
217             <extends: Plosurin::Template::Grammar>
218             <matchline>
219             \A <File> \Z
220             }xms;
221 6 50       174 if ( $ref =~ $r ) {
222 6         78 return {%/}->{File};
223             }
224 0         0 undef;
225             }
226              
227             =head2 as_perl5 { package=>"MyApp::Tmpl" }, $node1[, $noden]
228              
229             Export nodes as perl5 package
230              
231             =cut
232              
233 2     2   18 use Data::Dumper;
  2         5  
  2         554  
234              
235             sub as_perl5 {
236 1     1 1 12 my $self = shift;
237 1         2 my $opt = shift;
238 1 50       4 return " need at least one $file" unless scalar(@_);
239 1 50       4 my @files = map { ( ref($_) eq 'ARRAY' ) ? @{$_} : ($_) } @_;
  1         7  
  0         0  
240 1         3 my @alltemplates = ();
241              
242 1   50     4 my $package = $opt->{package} || die "
243             use as_perl5( { package => ... } ) !";
244              
245 1         6 my $ctx = new Plosurin::Context(@files);
246              
247 1         10 my $p5 = new Plosurin::To::Perl5(
248             'context' => $ctx,
249             'writer' => new Plosurin::Writer::Perl5,
250             'package' => $package,
251             );
252 1         8 $p5->start_write();
253 1         5 $p5->write(@files);
254 1         4 $p5->end_write();
255 1         4 my $res = $p5->wr->{code};
256 1 50       10 wantarray() ? ( $res, @{ $p5->{tmpls} } ) : $res;
  0            
257             }
258              
259             1;
260             __END__
261              
262             =head1 SEE ALSO
263              
264             Closure Templates Documentation L<http://code.google.com/closure/templates/docs/overview.html>
265              
266             Perl 6 implementation L<https://github.com/zag/plosurin>
267              
268              
269             =head1 AUTHOR
270              
271             Zahatski Aliaksandr, <zag@cpan.org>
272              
273             =head1 COPYRIGHT AND LICENSE
274              
275             Copyright (C) 2011 by Zahatski Aliaksandr
276              
277             This library is free software; you can redistribute it and/or modify
278             it under the same terms as Perl itself.
279              
280             =cut
281