File Coverage

blib/lib/Dancer/Template/Simple.pm
Criterion Covered Total %
statement 89 89 100.0
branch 38 44 86.3
condition 7 7 100.0
subroutine 12 12 100.0
pod 2 3 66.6
total 148 155 95.4


line stmt bran cond sub pod time code
1             package Dancer::Template::Simple;
2             our $AUTHORITY = 'cpan:SUKRIA';
3             #ABSTRACT: pure Perl 5 template engine for Dancer
4             $Dancer::Template::Simple::VERSION = '1.3521';
5 194     194   116313 use strict;
  194         470  
  194         5861  
6 194     194   1037 use warnings;
  194         471  
  194         4641  
7 194     194   1241 use Carp;
  194         496  
  194         11977  
8              
9 194     194   1319 use base 'Dancer::Template::Abstract';
  194         495  
  194         97919  
10             Dancer::Template::Simple->attributes('start_tag', 'stop_tag');
11 194     194   1536 use Dancer::FileUtils 'read_file_content';
  194         535  
  194         9677  
12 194     194   1333 use Dancer::Exception qw(:all);
  194         480  
  194         186925  
13              
14             sub init {
15 248     248 1 555 my $self = shift;
16 248         1412 my $settings = $self->config;
17              
18 248   100     1451 my $start = $settings->{'start_tag'} || '<%';
19 248   100     1129 my $stop = $settings->{'stop_tag'} || '%>';
20              
21 248 50       853 $self->start_tag($start) unless defined $self->start_tag;
22 248 50       751 $self->stop_tag($stop) unless defined $self->stop_tag;
23             }
24              
25             sub render {
26 98     98 1 4346 my ($self, $template, $tokens) = @_;
27 98         195 my $content;
28              
29 98         289 $content = _read_content_from_template($template);
30 97         329 $content = $self->parse_branches($content, $tokens);
31              
32 97         705 return $content;
33             }
34              
35             sub parse_branches {
36 97     97 0 236 my ($self, $content, $tokens) = @_;
37 97         301 my ($start, $stop) = ($self->start_tag, $self->stop_tag);
38              
39 97         199 my @buffer;
40 97         183 my $prefix = "";
41 97         192 my $should_bufferize = 1;
42 97         171 my $bufferize_if_token = 0;
43              
44             # $content =~ s/\Q${start}\E(\S)/${start} $1/sg;
45             # $content =~ s/(\S)\Q${stop}\E/$1 ${stop}/sg;
46              
47             # we get here a list of tokens without the start/stop tags
48 97         2125 my @full = split(/\Q$start\E\s*(.*?)\s*\Q$stop\E/, $content);
49              
50             # and here a list of tokens without variables
51 97         1263 my @flat = split(/\Q$start\E\s*.*?\s*\Q$stop\E/, $content);
52              
53             # eg: for 'foo=<% var %>'
54             # @full = ('foo=', 'var')
55             # @flat = ('foo=')
56              
57 97         231 my $flat_index = 0;
58 97         215 my $full_index = 0;
59 97         244 for my $word (@full) {
60              
61             # flat word, nothing to do
62 735 100 100     2523 if (defined $flat[$flat_index]
63             && ($flat[$flat_index] eq $full[$full_index]))
64             {
65 414 100       957 push @buffer, $word if $should_bufferize;
66 414         601 $flat_index++;
67 414         548 $full_index++;
68 414         759 next;
69             }
70              
71 321         699 my @to_parse = ($word);
72 321 100       913 @to_parse = split(/\s+/, $word) if $word =~ /\s+/;
73              
74 321         563 for my $w (@to_parse) {
75              
76 323 100       1315 if ($w eq 'if') {
    100          
    100          
    100          
    50          
77 2         6 $bufferize_if_token = 1;
78             }
79             elsif ($w eq 'else') {
80 2         4 $should_bufferize = !$should_bufferize;
81             }
82             elsif ($w eq 'end') {
83 2         3 $should_bufferize = 1;
84             }
85             elsif ($bufferize_if_token) {
86 2         6 my $bool = _find_value_from_token_name($w, $tokens);
87 2 100       5 $should_bufferize = _interpolate_value($bool) ? 1 : 0;
88 2         5 $bufferize_if_token = 0;
89             }
90             elsif ($should_bufferize) {
91 315         2254 my $val =
92             _interpolate_value(_find_value_from_token_name($w, $tokens));
93 315         657 push @buffer, $val;
94             }
95             }
96              
97 321         525 $full_index++;
98             }
99              
100 97         904 return join "", @buffer;
101             }
102              
103             # private
104              
105             sub _read_content_from_template {
106 98     98   232 my ($template) = @_;
107 98         206 my $content = undef;
108              
109 98 100       311 if (ref($template)) {
110 46         111 $content = $$template;
111             }
112             else {
113 52 100       848 raise core_template => "'$template' is not a regular file"
114             unless -f $template;
115 51         281 $content = read_file_content($template);
116 51 50       190 raise core_template => "unable to read content for file $template"
117             if not defined $content;
118             }
119 97         223 return $content;
120             }
121              
122             sub _find_value_from_token_name {
123 317     317   622 my ($key, $tokens) = @_;
124 317         455 my $value = undef;
125              
126 317         822 my @elements = split /\./, $key;
127 317         558 foreach my $e (@elements) {
128 348 100       770 if (not defined $value) {
    100          
    50          
129 317         715 $value = $tokens->{$e};
130             }
131             elsif (ref($value) eq 'HASH') {
132 20         50 $value = $value->{$e};
133             }
134             elsif (ref($value)) {
135 11         21 local $@;
136 11         20 eval { $value = $value->$e };
  11         76  
137 11 100       44 $value = "" if $@;
138             }
139             }
140 317         845 return $value;
141             }
142              
143             sub _interpolate_value {
144 317     317   555 my ($value) = @_;
145 317 100       862 if (ref($value) eq 'CODE') {
    100          
146 2         3 local $@;
147 2         8 eval { $value = $value->() };
  2         6  
148 2 50       10 $value = "" if $@;
149             }
150             elsif (ref($value) eq 'ARRAY') {
151 2         5 $value = "@{$value}";
  2         11  
152             }
153              
154 317 100       617 $value = "" if not defined $value;
155 317         532 return $value;
156             }
157              
158             1;
159              
160             __END__