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.3520';
5 194     194   117324 use strict;
  194         494  
  194         6059  
6 194     194   1060 use warnings;
  194         475  
  194         4665  
7 194     194   1256 use Carp;
  194         430  
  194         12531  
8              
9 194     194   1380 use base 'Dancer::Template::Abstract';
  194         492  
  194         97956  
10             Dancer::Template::Simple->attributes('start_tag', 'stop_tag');
11 194     194   1585 use Dancer::FileUtils 'read_file_content';
  194         540  
  194         9982  
12 194     194   1366 use Dancer::Exception qw(:all);
  194         500  
  194         192857  
13              
14             sub init {
15 248     248 1 511 my $self = shift;
16 248         1467 my $settings = $self->config;
17              
18 248   100     1498 my $start = $settings->{'start_tag'} || '<%';
19 248   100     1114 my $stop = $settings->{'stop_tag'} || '%>';
20              
21 248 50       829 $self->start_tag($start) unless defined $self->start_tag;
22 248 50       839 $self->stop_tag($stop) unless defined $self->stop_tag;
23             }
24              
25             sub render {
26 98     98 1 4299 my ($self, $template, $tokens) = @_;
27 98         192 my $content;
28              
29 98         272 $content = _read_content_from_template($template);
30 97         319 $content = $self->parse_branches($content, $tokens);
31              
32 97         675 return $content;
33             }
34              
35             sub parse_branches {
36 97     97 0 240 my ($self, $content, $tokens) = @_;
37 97         284 my ($start, $stop) = ($self->start_tag, $self->stop_tag);
38              
39 97         195 my @buffer;
40 97         213 my $prefix = "";
41 97         159 my $should_bufferize = 1;
42 97         204 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         2160 my @full = split(/\Q$start\E\s*(.*?)\s*\Q$stop\E/, $content);
49              
50             # and here a list of tokens without variables
51 97         1240 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         227 my $flat_index = 0;
58 97         202 my $full_index = 0;
59 97         258 for my $word (@full) {
60              
61             # flat word, nothing to do
62 735 100 100     2848 if (defined $flat[$flat_index]
63             && ($flat[$flat_index] eq $full[$full_index]))
64             {
65 414 100       1014 push @buffer, $word if $should_bufferize;
66 414         561 $flat_index++;
67 414         533 $full_index++;
68 414         729 next;
69             }
70              
71 321         689 my @to_parse = ($word);
72 321 100       906 @to_parse = split(/\s+/, $word) if $word =~ /\s+/;
73              
74 321         556 for my $w (@to_parse) {
75              
76 323 100       1273 if ($w eq 'if') {
    100          
    100          
    100          
    50          
77 2         4 $bufferize_if_token = 1;
78             }
79             elsif ($w eq 'else') {
80 2         8 $should_bufferize = !$should_bufferize;
81             }
82             elsif ($w eq 'end') {
83 2         3 $should_bufferize = 1;
84             }
85             elsif ($bufferize_if_token) {
86 2         4 my $bool = _find_value_from_token_name($w, $tokens);
87 2 100       4 $should_bufferize = _interpolate_value($bool) ? 1 : 0;
88 2         4 $bufferize_if_token = 0;
89             }
90             elsif ($should_bufferize) {
91 315         623 my $val =
92             _interpolate_value(_find_value_from_token_name($w, $tokens));
93 315         653 push @buffer, $val;
94             }
95             }
96              
97 321         544 $full_index++;
98             }
99              
100 97         903 return join "", @buffer;
101             }
102              
103             # private
104              
105             sub _read_content_from_template {
106 98     98   211 my ($template) = @_;
107 98         205 my $content = undef;
108              
109 98 100       291 if (ref($template)) {
110 46         131 $content = $$template;
111             }
112             else {
113 52 100       911 raise core_template => "'$template' is not a regular file"
114             unless -f $template;
115 51         270 $content = read_file_content($template);
116 51 50       184 raise core_template => "unable to read content for file $template"
117             if not defined $content;
118             }
119 97         231 return $content;
120             }
121              
122             sub _find_value_from_token_name {
123 317     317   622 my ($key, $tokens) = @_;
124 317         508 my $value = undef;
125              
126 317         748 my @elements = split /\./, $key;
127 317         542 foreach my $e (@elements) {
128 348 100       732 if (not defined $value) {
    100          
    50          
129 317         703 $value = $tokens->{$e};
130             }
131             elsif (ref($value) eq 'HASH') {
132 20         49 $value = $value->{$e};
133             }
134             elsif (ref($value)) {
135 11         19 local $@;
136 11         51 eval { $value = $value->$e };
  11         68  
137 11 100       47 $value = "" if $@;
138             }
139             }
140 317         862 return $value;
141             }
142              
143             sub _interpolate_value {
144 317     317   629 my ($value) = @_;
145 317 100       948 if (ref($value) eq 'CODE') {
    100          
146 2         3 local $@;
147 2         4 eval { $value = $value->() };
  2         5  
148 2 50       11 $value = "" if $@;
149             }
150             elsif (ref($value) eq 'ARRAY') {
151 2         3 $value = "@{$value}";
  2         8  
152             }
153              
154 317 100       647 $value = "" if not defined $value;
155 317         548 return $value;
156             }
157              
158             1;
159              
160             __END__