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   33040 use strict;
  1         2  
  1         25  
4 1     1   4 use warnings;
  1         1  
  1         26  
5 1     1   2 use File::Spec;
  1         1  
  1         11  
6 1     1   372 use Text::MicroTemplate;
  1         1  
  1         42  
7              
8 1     1   5 use Carp qw(croak);
  1         1  
  1         535  
9              
10             our @ISA = qw(Text::MicroTemplate);
11              
12             sub new {
13 7     7 1 3202 my $klass = shift;
14 7         35 my $self = $klass->SUPER::new(@_);
15 7   100     20 $self->{include_path} ||= [ '.' ];
16 7 100       18 unless (defined $self->{open_layer}) {
17 6         9 $self->{open_layer} = ':utf8';
18             }
19 7 100       16 unless (ref $self->{include_path}) {
20 6         13 $self->{include_path} = [ $self->{include_path} ];
21             }
22 7   100     24 $self->{use_cache} ||= 0;
23 7         12 $self->{cache} = {}; # file => { mtime, sub }
24 7         11 $self;
25             }
26              
27             sub include_path {
28 1     1 1 5 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       5 $self->{open_layer} = $_[0]
36             if @_;
37 1         3 $self->{open_layer};
38             }
39              
40             sub use_cache {
41 2     2 1 2 my $self = shift;
42 2 100       9 $self->{use_cache} = $_[0]
43             if @_;
44 2         5 $self->{use_cache};
45             }
46              
47             sub build_file {
48 26     26 1 29 my ($self, $file) = @_;
49             # return cached entry
50 26 100       53 if ($self->{use_cache} == 2) {
51 1 50       4 if (my $e = $self->{cache}->{$file}) {
52 1         27 return $e->[1];
53             }
54             }
55             # setup ($filepath, @st)
56 25         16 my ($filepath, @st);
57 25 100       155 if (File::Spec->file_name_is_absolute($file)) {
58             # absolute path
59 1         64 $filepath = $file;
60 1         14 @st = stat $filepath;
61             } else {
62             # relative path, search "include_path"s
63 24         20 foreach my $path (@{$self->{include_path}}) {
  24         44  
64 24         39 $filepath = $path . '/' . $file;
65 24 50       437 @st = stat $filepath
66             and last;
67             }
68             }
69 25 50       62 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       53 if (my $e = $self->{cache}->{$file}) {
74 3 100       53 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       565 open my $fh, "<$self->{open_layer}", $filepath
80             or croak "failed to open:$filepath:$!";
81 23         20 my $src = do { local $/; <$fh> };
  23         63  
  23         317  
82 23         129 close $fh;
83 23         70 $self->parse($src);
84 23         24 local $Text::MicroTemplate::_mt_setter = 'my $_mt = shift;';
85 23         53 my $f = $self->build();
86 23 100       47 $self->{cache}->{$file} = [
87             $st[9], # mtime
88             $f,
89             ] if $self->{use_cache};
90 23         461 return $f;
91             }
92              
93             sub render_file {
94 26     26 1 229 my $self = shift;
95 26         28 my $file = shift;
96 26         45 $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         7 my @args = @_;
103 5         4 my $mtref = do {
104 1     1   4 no strict 'refs';
  1         1  
  1         96  
105 5         4 ${"$self->{package_name}::_MTREF"};
  5         14  
106             };
107 5         6 my $before = $$mtref;
108 5         4 $$mtref = '';
109             return sub {
110 5     5   5 my $inner_func = shift;
111 5         83 $inner_func->(@_);
112 5         16 $$mtref =
113             $before . $self->render_file($file, Text::MicroTemplate::encoded_string($$mtref), @args)->as_string;
114             }
115 5         21 }
116              
117             1;
118             __END__