line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Text::MicroMason::TemplateDir; |
2
|
|
|
|
|
|
|
|
3
|
6
|
|
|
6
|
|
1147
|
use strict; |
|
6
|
|
|
|
|
4
|
|
|
6
|
|
|
|
|
142
|
|
4
|
6
|
|
|
6
|
|
19
|
use File::Spec; |
|
6
|
|
|
|
|
5
|
|
|
6
|
|
|
|
|
85
|
|
5
|
6
|
|
|
6
|
|
14
|
use Cwd; |
|
6
|
|
|
|
|
5
|
|
|
6
|
|
|
|
|
1969
|
|
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
###################################################################### |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
sub prepare { |
10
|
35
|
|
|
35
|
1
|
35
|
my ( $self, $src_type, $src_data ) = @_; |
11
|
|
|
|
|
|
|
|
12
|
35
|
100
|
|
|
|
78
|
return $self->NEXT('prepare', $src_type, $src_data ) |
13
|
|
|
|
|
|
|
unless $src_type eq 'file'; |
14
|
|
|
|
|
|
|
|
15
|
28
|
|
|
|
|
57
|
my $path = $self->resolve_path($src_data); |
16
|
28
|
|
|
|
|
129
|
return $self->NEXT('prepare', 'file' => $path, source_file => $path ); |
17
|
|
|
|
|
|
|
} |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
sub resolve_path { |
20
|
24
|
|
|
24
|
0
|
19
|
my ($self, $src_data) = @_; |
21
|
|
|
|
|
|
|
|
22
|
24
|
|
|
|
|
29
|
my $current = $self->{source_file}; |
23
|
24
|
|
|
|
|
35
|
my $rootdir = $self->template_root(); |
24
|
|
|
|
|
|
|
|
25
|
24
|
100
|
66
|
|
|
196
|
my $base = File::Spec->file_name_is_absolute($src_data) || |
26
|
|
|
|
|
|
|
! $current ? $rootdir : ( File::Spec->splitpath( $current ) )[1]; |
27
|
|
|
|
|
|
|
|
28
|
24
|
|
|
|
|
187
|
return File::Spec->catfile( $base, $src_data ); |
29
|
|
|
|
|
|
|
} |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
sub template_root { |
32
|
24
|
|
|
24
|
1
|
17
|
my $self = shift; |
33
|
24
|
50
|
100
|
|
|
73
|
return $self->{template_root} || '.' unless @_; |
34
|
|
|
|
|
|
|
|
35
|
0
|
|
|
|
|
0
|
$self->{template_root} = shift; |
36
|
|
|
|
|
|
|
} |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
sub cache_key { |
39
|
10
|
|
|
10
|
0
|
52
|
my $self = shift; |
40
|
10
|
|
|
|
|
11
|
my ($src_type, $src_data, %options) = @_; |
41
|
10
|
100
|
|
|
|
20
|
return $self->NEXT('cache_key', @_) unless $src_type eq 'file'; |
42
|
8
|
|
|
|
|
14
|
return $self->resolve_path($src_data); |
43
|
|
|
|
|
|
|
} |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
# $contents = $mason->read_file( $filename ); |
47
|
|
|
|
|
|
|
sub read_file { |
48
|
28
|
|
|
28
|
1
|
280
|
my ( $self, $file ) = @_; |
49
|
|
|
|
|
|
|
|
50
|
28
|
50
|
|
|
|
92
|
if ( my $root = $self->{strict_root} ) { |
51
|
0
|
0
|
|
|
|
0
|
$root = $self->template_root if $root eq '1'; |
52
|
0
|
|
|
|
|
0
|
my $path = Cwd::abs_path($file); |
53
|
0
|
0
|
|
|
|
0
|
my $root_path = Cwd::abs_path($root) |
54
|
|
|
|
|
|
|
or $self->croak_msg("Text::MicroMason::TemplateDir: Strict root '$root' doesn't seem to exist"); |
55
|
|
|
|
|
|
|
# warn "Checking for '$root_path' in '$path' (file $file)\n"; |
56
|
0
|
0
|
|
|
|
0
|
( $path =~ /\A\Q$root_path\E/) |
57
|
|
|
|
|
|
|
or $self->croak_msg("Text::MicroMason::TemplateDir: Template '$path' not in required base path '$root_path'"); |
58
|
|
|
|
|
|
|
} |
59
|
|
|
|
|
|
|
|
60
|
28
|
|
|
|
|
56
|
return $self->NEXT('read_file', $file ); |
61
|
|
|
|
|
|
|
} |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
###################################################################### |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
1; |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
###################################################################### |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
=head1 NAME |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
Text::MicroMason::TemplateDir - Use Base Directory and Relative Paths |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
=head1 SYNOPSIS |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
Instead of using this class directly, pass its name to be mixed in: |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
use Text::MicroMason; |
79
|
|
|
|
|
|
|
my $mason = Text::MicroMason->new( -TemplateDir, template_root=>'/foo' ); |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
Use the standard compile and execute methods to parse and evaluate templates: |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
print $mason->compile( file=>$filepath )->( 'name'=>'Dave' ); |
84
|
|
|
|
|
|
|
print $mason->execute( file=>$filepath, 'name'=>'Dave' ); |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
Templates stored in files are looked up relative to the template root: |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
print $mason->execute( file=>"includes/greeting.msn", 'name'=>'Charles'); |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
When including other files into a template you can use relative paths: |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
<& ../includes/greeting.msn, name => 'Alice' &> |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
=head1 DESCRIPTION |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
This module changes the resolution of files passed to compile() and execute() to be relative to a base directory path or to the currently executing template. |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
=head2 Supported Attributes |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
=over 4 |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
=item template_root |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
Base directory from which to find templates. |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
=item strict_root |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
Optional directory beyond which not to read files. If set to 1, uses |
111
|
|
|
|
|
|
|
template_root, Causes read_file to croak if any filename outside of the |
112
|
|
|
|
|
|
|
root is provided. (Note that this is not a chroot jail and only affects |
113
|
|
|
|
|
|
|
attempts to load a file as a template; for greater security see the |
114
|
|
|
|
|
|
|
chroot() builtin and L.) |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
=back |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
=head2 Private Methods |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
=over 4 |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
=item prepare |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
Intercepts uses of file templates and applies the base-path adjustment. |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
=item read_file |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
Intercepts file access to check for strict_root. |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
=back |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
=head2 EXCEPTIONS |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
The following additional exceptions are generated by |
135
|
|
|
|
|
|
|
Text::MicroMason::TemplateDir when appropriate: |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
=over 4 |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
=item * |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
Text::MicroMason::TemplateDir: Strict root '%s' doesn't seem to exist |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
The strict_root directory (or template_root if strict_root is '1') |
144
|
|
|
|
|
|
|
doesn't seem to exist. Strict root checking uses Cwd's abs_path(), and |
145
|
|
|
|
|
|
|
requires the strict_root directory to exist at the time the check is |
146
|
|
|
|
|
|
|
performed. |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
=item * |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
Text::MicroMason::TemplatePath: Template '%s' not in required base path '%s' |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
The template found in the configured template path was not within the |
153
|
|
|
|
|
|
|
configured strict_root directory. This may be caused by requesting an |
154
|
|
|
|
|
|
|
absolute template filename not within strict_root, or by specifying a |
155
|
|
|
|
|
|
|
strict_root which does not match the configured template path. |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
=back |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
=head1 SEE ALSO |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
For an overview of this templating framework, see L. |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
This is a mixin class intended for use with L. |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
For distribution, installation, support, copyright and license |
166
|
|
|
|
|
|
|
information, see L. |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
=cut |
169
|
|
|
|
|
|
|
|