Subject: | Preloading templates for dynamic include paths |
Template::Provider::Preload is currently not compatible with a scenario
where the template include path is updated at runtime via
"additional_template_paths". The patch introduces a new config param
'PRECACHE_ADDITIONAL_TEMPLATE_PATHS' which can be used to pre-load
templates which *might* be needed from an additional template path at
runtime. The patch requires the patch from RT #59417 to be applied.
Subject: | Template-Provider-Preload.pm-patched0.05withRT59417-AdditionalTemplatePaths.diff |
--- Preload.pm-0.05 2010-08-20 12:04:14.000000000 +0200
+++ Preload.pm 2010-08-20 14:04:35.000000000 +0200
@@ -166,7 +166,7 @@
use vars qw{$VERSION};
BEGIN {
- $VERSION = '0.05';
+ $VERSION = '0.06';
}
@@ -185,6 +185,7 @@
PREFETCH => '*.tt',
INCLUDE_PATH => 'my/templates',
COMPILE_DIR => 'my/cache',
+ PRECACHE_ADDITIONAL_TEMPLATE_PATHS => [ 'my/additional_templates', ],
});
The C<new> constructor accepts all the same parameters as the underlying
@@ -206,6 +207,10 @@
the reference will be flattened to a list, allowing you to provide more
than one file type string to C<prefetch>.
+The C<PRECACHE_ADDITIONAL_TEMPLATE_PATHS> param indicates that the given
+list of directory should be included when precaching and prefetching templates.
+This is necessary if you dynamically adjust the INCLUDE_PATH at runtime.
+
Returns a L<Template::Provider::Preload> object, or throws an excpetion
(dies) on error.
@@ -216,6 +221,7 @@
my $param = shift;
my $precache = delete $param->{PRECACHE};
my $prefetch = delete $param->{PREFETCH};
+ my $precache_additional_paths = delete $param->{PRECACHE_ADDITIONAL_TEMPLATE_PATHS};
# Create the provider as normal
my $self = $class->SUPER::new(
@@ -227,6 +233,11 @@
$self->{PRECACHE} = {};
}
+ # Set the additional template paths to be precached, if given
+ if ( defined $precache_additional_paths ) {
+ $self->{PRECACHE_ADDITIONAL_PATHS} = $precache_additional_paths;
+ }
+
# Prefetch immediately if needed
if ( defined $prefetch ) {
my @args = Params::Util::_ARRAYLIKE($prefetch)
@@ -277,11 +288,14 @@
Selection of the files to compile is done via a L<File::Find::Rule> search
across all C<INCLUDE_PATH> directories. If the same file exists within more
-than one C<INCLUDE_PATH> directory, only the first one will be compiled.
+than one C<INCLUDE_PATH> directory, only the first one will be compiled unless
+you provide a list of extra include paths via C<PRECACHE_ADDITIONAL_TEMPLATE_PATHS>.
+This will be needed if you dynamically adjust the C<INCLUDE_PATH> via 'additional_template_paths'
+at runtime.
In the canonical usage, the C<prefetch> method takes a single parameter,
which should be a L<File::Find::Rule> object. The method will call C<file>
-and C<relative> on the filter you pass in, so you should consider the
+on the filter you pass in, so you should consider the
C<prefetch> method to be destructive to the filter.
As a convenience, if the method is passed a series of strings, a new
@@ -325,10 +339,10 @@
sub _find {
my $self = shift;
- my $filter = $self->_filter(@_)->relative->file;
- my $paths = $self->paths;
+ my $filter = $self->_filter(@_)->file;
+
my %seen = ();
- return grep { not $seen{$_}++ } map { $filter->in($_) } @$paths;
+ return grep { not $seen{$_}++ } map { $filter->in($_) } ( @{$self->paths}, @{$self->{PRECACHE_ADDITIONAL_PATHS}} );
}
sub _filter {
@@ -360,9 +374,20 @@
# If caching and we get a name in the cache, return it
if ( $self->{PRECACHE} and not ref $name ) {
- my $cached = $self->{PRECACHE}->{$name};
+ my $cached;
+ # Check if we got an absolute path
+ if ( substr($name,0,1) eq '/' ) {
+ $cached = $self->{PRECACHE}->{$name};
return @$cached if $cached;
}
+ # If not, loop over all INCLUDE_PATHs to check for a cached template
+ else {
+ foreach my $path ( @{ $self->paths } ) {
+ $cached = $self->{PRECACHE}->{$path . '/' . $name};
+ return @$cached if $cached;
+ }
+ }
+ }
# Otherwise, hand off to the child
return $self->_OBJECT_->fetch( $name, @_ );