File Coverage

blib/lib/Text/MicroTemplate/File.pm
Criterion Covered Total %
statement 74 77 96.1
branch 22 28 78.5
condition 4 4 100.0
subroutine 13 14 92.8
pod 7 8 87.5
total 120 131 91.6


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