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.3514_04'; # TRIAL
5             $Dancer::Template::Simple::VERSION = '1.351404';
6 195     195   98068 use strict;
  195         391  
  195         5003  
7 195     195   890 use warnings;
  195         339  
  195         4309  
8 195     195   862 use Carp;
  195         367  
  195         12136  
9              
10 195     195   1248 use base 'Dancer::Template::Abstract';
  195         402  
  195         79936  
11             Dancer::Template::Simple->attributes('start_tag', 'stop_tag');
12 195     195   1331 use Dancer::FileUtils 'read_file_content';
  195         378  
  195         7738  
13 195     195   1127 use Dancer::Exception qw(:all);
  195         466  
  195         156079  
14              
15             sub init {
16 249     249 1 442 my $self = shift;
17 249         1088 my $settings = $self->config;
18              
19 249   100     1211 my $start = $settings->{'start_tag'} || '<%';
20 249   100     955 my $stop = $settings->{'stop_tag'} || '%>';
21              
22 249 50       693 $self->start_tag($start) unless defined $self->start_tag;
23 249 50       796 $self->stop_tag($stop) unless defined $self->stop_tag;
24             }
25              
26             sub render {
27 98     98 1 4255 my ($self, $template, $tokens) = @_;
28 98         140 my $content;
29              
30 98         251 $content = _read_content_from_template($template);
31 97         306 $content = $self->parse_branches($content, $tokens);
32              
33 97         563 return $content;
34             }
35              
36             sub parse_branches {
37 97     97 0 224 my ($self, $content, $tokens) = @_;
38 97         290 my ($start, $stop) = ($self->start_tag, $self->stop_tag);
39              
40 97         185 my @buffer;
41 97         151 my $prefix = "";
42 97         139 my $should_bufferize = 1;
43 97         149 my $bufferize_if_token = 0;
44              
45             # $content =~ s/\Q${start}\E(\S)/${start} $1/sg;
46             # $content =~ s/(\S)\Q${stop}\E/$1 ${stop}/sg;
47              
48             # we get here a list of tokens without the start/stop tags
49 97         1778 my @full = split(/\Q$start\E\s*(.*?)\s*\Q$stop\E/, $content);
50              
51             # and here a list of tokens without variables
52 97         1098 my @flat = split(/\Q$start\E\s*.*?\s*\Q$stop\E/, $content);
53              
54             # eg: for 'foo=<% var %>'
55             # @full = ('foo=', 'var')
56             # @flat = ('foo=')
57              
58 97         193 my $flat_index = 0;
59 97         155 my $full_index = 0;
60 97         210 for my $word (@full) {
61              
62             # flat word, nothing to do
63 735 100 100     2089 if (defined $flat[$flat_index]
64             && ($flat[$flat_index] eq $full[$full_index]))
65             {
66 414 100       807 push @buffer, $word if $should_bufferize;
67 414         445 $flat_index++;
68 414         446 $full_index++;
69 414         584 next;
70             }
71              
72 321         593 my @to_parse = ($word);
73 321 100       793 @to_parse = split(/\s+/, $word) if $word =~ /\s+/;
74              
75 321         446 for my $w (@to_parse) {
76              
77 323 100       998 if ($w eq 'if') {
    100          
    100          
    100          
    50          
78 2         4 $bufferize_if_token = 1;
79             }
80             elsif ($w eq 'else') {
81 2         4 $should_bufferize = !$should_bufferize;
82             }
83             elsif ($w eq 'end') {
84 2         3 $should_bufferize = 1;
85             }
86             elsif ($bufferize_if_token) {
87 2         4 my $bool = _find_value_from_token_name($w, $tokens);
88 2 100       5 $should_bufferize = _interpolate_value($bool) ? 1 : 0;
89 2         4 $bufferize_if_token = 0;
90             }
91             elsif ($should_bufferize) {
92 315         522 my $val =
93             _interpolate_value(_find_value_from_token_name($w, $tokens));
94 315         872 push @buffer, $val;
95             }
96             }
97              
98 321         452 $full_index++;
99             }
100              
101 97         811 return join "", @buffer;
102             }
103              
104             # private
105              
106             sub _read_content_from_template {
107 98     98   213 my ($template) = @_;
108 98         172 my $content = undef;
109              
110 98 100       251 if (ref($template)) {
111 46         82 $content = $$template;
112             }
113             else {
114 52 100       746 raise core_template => "'$template' is not a regular file"
115             unless -f $template;
116 51         234 $content = read_file_content($template);
117 51 50       151 raise core_template => "unable to read content for file $template"
118             if not defined $content;
119             }
120 97         187 return $content;
121             }
122              
123             sub _find_value_from_token_name {
124 317     317   522 my ($key, $tokens) = @_;
125 317         396 my $value = undef;
126              
127 317         667 my @elements = split /\./, $key;
128 317         464 foreach my $e (@elements) {
129 348 100       584 if (not defined $value) {
    100          
    50          
130 317         608 $value = $tokens->{$e};
131             }
132             elsif (ref($value) eq 'HASH') {
133 20         38 $value = $value->{$e};
134             }
135             elsif (ref($value)) {
136 11         16 local $@;
137 11         16 eval { $value = $value->$e };
  11         43  
138 11 100       34 $value = "" if $@;
139             }
140             }
141 317         677 return $value;
142             }
143              
144             sub _interpolate_value {
145 317     317   460 my ($value) = @_;
146 317 100       777 if (ref($value) eq 'CODE') {
    100          
147 2         2 local $@;
148 2         3 eval { $value = $value->() };
  2         4  
149 2 50       7 $value = "" if $@;
150             }
151             elsif (ref($value) eq 'ARRAY') {
152 2         3 $value = "@{$value}";
  2         6  
153             }
154              
155 317 100       510 $value = "" if not defined $value;
156 317         491 return $value;
157             }
158              
159             1;
160              
161             __END__