Skip Menu |

This queue is for tickets about the Template-Provider-Preload CPAN distribution.

Report information
The Basics
Id: 60551
Status: new
Priority: 0/
Queue: Template-Provider-Preload

People
Owner: Nobody in particular
Requestors: PEPL [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 0.05
Fixed in: 0.05



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, @_ );