File Coverage

blib/lib/Text/MicroTemplate/File.pm
Criterion Covered Total %
statement 77 78 98.7
branch 22 28 78.5
condition 4 4 100.0
subroutine 14 14 100.0
pod 7 7 100.0
total 124 131 94.6


line stmt bran cond sub pod time code
1             package Text::MicroTemplate::File;
2              
3 1     1   37981 use strict;
  1         1  
  1         24  
4 1     1   4 use warnings;
  1         1  
  1         27  
5 1     1   3 use File::Spec;
  1         1  
  1         11  
6 1     1   279 use Text::MicroTemplate;
  1         2  
  1         41  
7              
8 1     1   4 use Carp qw(croak);
  1         0  
  1         368  
9              
10             our @ISA = qw(Text::MicroTemplate);
11              
12             sub new {
13 7     7 1 3089 my $klass = shift;
14 7         34 my $self = $klass->SUPER::new(@_);
15 7   100     18 $self->{include_path} ||= [ '.' ];
16 7 100       14 unless (defined $self->{open_layer}) {
17 6         11 $self->{open_layer} = ':utf8';
18             }
19 7 100       13 unless (ref $self->{include_path}) {
20 6         10 $self->{include_path} = [ $self->{include_path} ];
21             }
22 7   100     25 $self->{use_cache} ||= 0;
23 7         11 $self->{cache} = {}; # file => { mtime, sub }
24 7         12 $self;
25             }
26              
27             sub include_path {
28 1     1 1 4 my $self = shift;
29 1 50       3 croak "This is readonly accessor" if @_;
30 1         6 $self->{include_path};
31             }
32              
33             sub open_layer {
34 1     1 1 2 my $self = shift;
35 1 50       3 $self->{open_layer} = $_[0]
36             if @_;
37 1         4 $self->{open_layer};
38             }
39              
40             sub use_cache {
41 2     2 1 5 my $self = shift;
42 2 100       7 $self->{use_cache} = $_[0]
43             if @_;
44 2         5 $self->{use_cache};
45             }
46              
47             sub build_file {
48 26     26 1 27 my ($self, $file) = @_;
49             # return cached entry
50 26 100       49 if ($self->{use_cache} == 2) {
51 1 50       3 if (my $e = $self->{cache}->{$file}) {
52 1         25 return $e->[1];
53             }
54             }
55             # setup ($filepath, @st)
56 25         20 my ($filepath, @st);
57 25 100       138 if (File::Spec->file_name_is_absolute($file)) {
58             # absolute path
59 1         3 $filepath = $file;
60 1         83 @st = stat $filepath;
61             } else {
62             # relative path, search "include_path"s
63 24         18 foreach my $path (@{$self->{include_path}}) {
  24         42  
64 24         33 $filepath = $path . '/' . $file;
65 24 50       393 @st = stat $filepath
66             and last;
67             }
68             }
69 25 50       55 croak "could not find template file: $file (include_path: @{$self->{include_path}})"
  0         0  
70             unless @st;
71            
72             # return cached entry after comparing mtime
73 25 100       57 if (my $e = $self->{cache}->{$file}) {
74 3 100       59 return $e->[1]
75             if $st[9] == $e->[0]; # compare mtime
76             }
77              
78             # read the file, parse, build, cache the entry if necessary, and return
79 23 50       591 open my $fh, "<$self->{open_layer}", $filepath
80             or croak "failed to open:$filepath:$!";
81 23         18 my $src = do { local $/; <$fh> };
  23         61  
  23         372  
82 23         124 close $fh;
83 23         68 $self->parse($src);
84 23         28 local $Text::MicroTemplate::_mt_setter = 'my $_mt = shift;';
85 23         50 my $f = $self->build();
86 23 100       50 $self->{cache}->{$file} = [
87             $st[9], # mtime
88             $f,
89             ] if $self->{use_cache};
90 23         533 return $f;
91             }
92              
93             sub render_file {
94 26     26 1 182 my $self = shift;
95 26         27 my $file = shift;
96 26         69 $self->build_file($file)->($self, @_);
97             }
98              
99             sub wrapper_file {
100 5     5 1 5 my $self = shift;
101 5         5 my $file = shift;
102 5         6 my @args = @_;
103 5         5 my $mtref = do {
104 1     1   4 no strict 'refs';
  1         2  
  1         94  
105 5         4 ${"$self->{package_name}::_MTREF"};
  5         13  
106             };
107 5         7 my $before = $$mtref;
108 5         2 $$mtref = '';
109             return sub {
110 5     5   3 my $inner_func = shift;
111 5         80 $inner_func->(@_);
112 5         12 $$mtref =
113             $before . $self->render_file($file, Text::MicroTemplate::encoded_string($$mtref), @args)->as_string;
114             }
115 5         19 }
116              
117             1;
118             __END__