File Coverage

lib/Template/Plugin/Next.pm
Criterion Covered Total %
statement 57 65 87.6
branch 11 18 61.1
condition 5 10 50.0
subroutine 9 11 81.8
pod 4 4 100.0
total 86 108 79.6


line stmt bran cond sub pod time code
1             #
2             # This file is part of Template-Plugin-Next
3             #
4             # This software is copyright (c) 2017 by Alexander Kühne.
5             #
6             # This is free software; you can redistribute it and/or modify it under
7             # the same terms as the Perl 5 programming language system itself.
8             #
9             package Template::Plugin::Next;
10             # ABSTRACT: include the 'next' template file with identical relative path
11             $Template::Plugin::Next::VERSION = '0.04';
12 1     1   44519 use warnings;
  1         3  
  1         33  
13 1     1   3 use strict;
  1         2  
  1         22  
14              
15 1     1   2 use base qw( Template::Plugin );
  1         1  
  1         442  
16 1     1   484 use Template::Plugin ();
  1         1  
  1         11  
17 1     1   3 use Template::Exception ();
  1         1  
  1         14  
18              
19 1     1   3 use File::Spec ();
  1         1  
  1         450  
20              
21              
22             sub new {
23             # called as Template::Plugin::Next->new($context)
24 4     4 1 10561 my ($class, $context, %params) = @_;
25              
26 4         10 my $self =
27             bless {
28             _CONTEXT => $context
29             }, $class;
30              
31 4         9 $self;
32             }
33              
34             sub error {
35 0     0 1 0 my $proto = shift;
36 0 0       0 die( ref( $_[0] ) ? @_ : do { $proto->SUPER::error(@_); Template::Exception->new( 'Next', $proto->SUPER::error ) } );
  0         0  
  0         0  
37             }
38              
39              
40             sub process {
41 2     2 1 43 my $self = shift;
42 2         3 my $params = shift;
43 2   50     13 my $localise = shift || 0;
44 2         8 my $context = $self->{_CONTEXT};
45 2         4 my $stash = $context->stash();
46              
47 2         27 my $name = $stash->get( 'component.name' ); # template file path not file name
48              
49 2   33     29 my $providers = $context->{ PREFIX_MAP }->{ default } || $context->{ LOAD_TEMPLATES };
50              
51 2         3 foreach my $provider ( grep { ref( $_ ) eq 'Template::Provider' } @$providers ) {
  2         5  
52             # we know only how to handle the standard behaviour of providers
53              
54 2         3 my $rel_path = $name;
55 2         2 my @include_paths = @{$provider->paths};
  2         6  
56             # include paths are returned in a list even if
57             # multiple include paths have been specified via a colon separated scalar
58              
59 2 50       45 $self->error( 'Not applicable. There is no second include path!' ) if scalar(@include_paths) == 1;
60            
61 2 100       14 if ( File::Spec->file_name_is_absolute( my $abs_path = $rel_path ) ) {
62             # this is for subsequent calls to NEXT
63             ( my( $include_path ), $rel_path ) =
64             @{
65 1 50 33     1 ( ( $stash->get( 'Next_' ) || $self->error( 'Could not find Next_ stash entry!' ) )->{$abs_path}
  1         14  
66             ||
67             $self->error( "Could not find abs path $abs_path in Next_ map!" )
68             )
69             };
70              
71 1         2 while ( @include_paths ) {
72 3 100       7 last if ( shift @include_paths ) eq $include_path;
73             }
74 1         16 $rel_path =~ s/^\///;
75              
76             } else {
77             # this is for the initial call to NEXT
78 1         3 while ( @include_paths ) {
79 2 100       5 last if scalar stat( _concat_path( (shift @include_paths ), $rel_path ) );
80             }
81             }
82              
83 2         5 foreach my $include_path ( @include_paths ) {
84 2         3 my $path = _concat_path( $include_path, $rel_path );
85              
86 2 50       31 if( scalar stat( $path ) ) {
87 2         2 my $template;
88             {
89             # make abs. template paths local to this template retrieval
90 2         2 local $provider->{ABSOLUTE} = 1;
  2         4  
91 2         6 $template = $context->template($path);
92             }
93 2 50       3238 defined $template || $self->error( $context->error );
94 2   100     19 my $map = $stash->get( 'Next_' ) || {};
95 2         11 $map->{$path} = [ $include_path, $rel_path ];
96 2         9 $stash->set( 'Next_' => $map );
97 2         13 return $context->process( $template, $params, $localise );
98             }
99             }
100             }
101              
102 0         0 $self->error( "No 'Next' template!" );
103             }
104              
105              
106             sub include {
107 0     0 1 0 my $self = shift;
108 0         0 $self->process( @_, 1 );
109             }
110              
111             sub _concat_path {
112 4     4   4 my ( $base_path, $append_dirs ) = @_;
113             # $base_dir: base path (no filename) as string
114             # $append_dirs: directories to append as string or an array reference
115            
116 4         17 my ($base_volume, $base_directories, $base_file) = File::Spec->splitpath( $base_path, 1 );
117             File::Spec->catpath(
118             $base_volume,
119             File::Spec->catdir(
120             File::Spec->splitdir( $base_directories ),
121 4 50       73 ( ref($append_dirs) ? @{$append_dirs} : File::Spec->splitdir( $append_dirs ) )
  0            
122             )
123             ,
124             $base_file
125             );
126             }
127              
128              
129             1; # End of Template::Plugin::Next
130              
131             __END__