[Templates] Calling templates with a fresh stash
darren chamberlain
dlc@users.sourceforge.net
Thu, 5 Sep 2002 10:21:27 -0400
--uAKRQypu60I7Lcqm
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
* alex <alex@state51.co.uk> [2002-09-05 08:42]:
> Would it make sense to have a parameter to INCLUDE and/or PROCESS to
> call a template using a new stash, only containing parameters taken
> from the parameters to INCLUDE or PROCESS?
>
> I think this would be handy for creating 'library' templates, having a
> totally separate namespace would help rule out potential bugs.
I can see how this could be implemented, but I'm not sure that I
completely understand why it would be needed.
I'm thinking a new directive, maybe DO, which would create a new stash,
and would function similarly to INCLUDE and PROCESS:
[% DO some/template var = "val" %]
> Might also be a bit faster than localising the stash.
Well, a new Template::Stash instance would have to be created, so the
overhead would be the call to new instead of clone.
(time passes....)
I've attached some patches to accomplish the above; there are 5 patches
that need to be applied, and Template::Grammar needs to be recreated
(this means you'll need Parse::YAPP installed). There are three new
constants in Template::Constants (determining the type of localization
needed for the stash) and some perl code-generating subs for
Directive.pm. Apply the patches like so, from the Template root (these
patches are against CVS; you might need a fresh checkout):
patch -p1 < parser.diff
patch -p1 < grammar.skel.diff
(cd parser; ./yc)
patch -p1 < context.diff
patch -p1 < constants.diff
patch -p1 < directive.diff
This will add a directive DO, which functions identically to INCLUDE and
PROCESS, except that the only variables available in the template
processed via DO are the ones defined in the call:
[% DO template one=1 two=2 %]
Defines only one and two for template.
All tests continue to pass.
(darren)
--
I believe in God, only I spell it Nature.
-- Frank Lloyd Wright
--uAKRQypu60I7Lcqm
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="context.diff"
*** Template2.orig/lib/Template/Context.pm Thu Aug 15 12:41:19 2002
--- Template2/lib/Template/Context.pm Thu Sep 5 09:53:33 2002
***************
*** 287,293 ****
my ($self, $template, $params, $localize) = @_;
my ($trim, $blocks) = @$self{ qw( TRIM BLOCKS ) };
my (@compiled, $name, $compiled);
! my ($stash, $tblocks, $error, $tmpout);
my $output = '';
$template = [ $template ] unless ref $template eq 'ARRAY';
--- 287,295 ----
my ($self, $template, $params, $localize) = @_;
my ($trim, $blocks) = @$self{ qw( TRIM BLOCKS ) };
my (@compiled, $name, $compiled);
! my ($oldstash, $stash, $tblocks, $error, $tmpout);
! $localize ||= Template::Constants::PROCESS_UNLOCALIZED;
! $params ||= { };
my $output = '';
$template = [ $template ] unless ref $template eq 'ARRAY';
***************
*** 302,310 ****
push(@compiled, $self->template($name));
}
! if ($localize) {
# localise the variable stash with any parameters passed
$stash = $self->{ STASH } = $self->{ STASH }->clone($params);
} else {
# update stash with any new parameters passed
$self->{ STASH }->update($params);
--- 304,315 ----
push(@compiled, $self->template($name));
}
! if ($localize == Template::Constants::PROCESS_LOCALIZED) {
# localise the variable stash with any parameters passed
$stash = $self->{ STASH } = $self->{ STASH }->clone($params);
+ } elsif ($localize == Template::Constants::PROCESS_NEW) {
+ $oldstash = $self->{ STASH };
+ $stash = $self->{ STASH } = Template::Config->stash($params);
} else {
# update stash with any new parameters passed
$self->{ STASH }->update($params);
***************
*** 349,357 ****
};
$error = $@;
! if ($localize) {
# ensure stash is delocalised before dying
$self->{ STASH } = $self->{ STASH }->declone();
}
$self->throw(ref $error
--- 354,364 ----
};
$error = $@;
! if ($localize == Template::Constants::PROCESS_LOCALIZED) {
# ensure stash is delocalised before dying
$self->{ STASH } = $self->{ STASH }->declone();
+ } elsif ($localize == Template::Constants::PROCESS_NEW) {
+ $self->{ STASH } = $oldstash;
}
$self->throw(ref $error
***************
*** 378,384 ****
sub include {
my ($self, $template, $params) = @_;
! return $self->process($template, $params, 'localize me!');
}
#------------------------------------------------------------------------
--- 385,396 ----
sub include {
my ($self, $template, $params) = @_;
! return $self->process($template, $params, Template::Constants::PROCESS_LOCALIZED);
! }
!
! sub do {
! my ($self, $template, $params) = @_;
! return $self->process($template, $params, Template::Constants::PROCESS_NEW);
}
#------------------------------------------------------------------------
--uAKRQypu60I7Lcqm
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="constants.diff"
*** Template2.orig/lib/Template/Constants.pm Fri Aug 16 04:41:16 2002
--- Template2/lib/Template/Constants.pm Thu Sep 5 09:19:08 2002
***************
*** 28,34 ****
use strict;
use vars qw( $VERSION @ISA @EXPORT_OK %EXPORT_TAGS );
! use vars qw( $DEBUG_OPTIONS @STATUS @ERROR @CHOMP @DEBUG);
@ISA = qw( Exporter );
$VERSION = sprintf("%d.%02d", q$Revision: 2.57 $ =~ /(\d+)\.(\d+)/);
--- 28,34 ----
use strict;
use vars qw( $VERSION @ISA @EXPORT_OK %EXPORT_TAGS );
! use vars qw( $DEBUG_OPTIONS @STATUS @ERROR @CHOMP @DEBUG @PROCESS );
@ISA = qw( Exporter );
$VERSION = sprintf("%d.%02d", q$Revision: 2.57 $ =~ /(\d+)\.(\d+)/);
***************
*** 79,84 ****
--- 79,89 ----
use constant DEBUG_CALLER => 4096; # add caller file/line
use constant DEBUG_FLAGS => 4096; # bitmask to extraxt flags
+ # PROCESS flags
+ use constant PROCESS_UNLOCALIZED => 0;
+ use constant PROCESS_LOCALIZED => 1;
+ use constant PROCESS_NEW => 2;
+
$DEBUG_OPTIONS = {
&DEBUG_OFF => off => off => &DEBUG_OFF,
&DEBUG_ON => on => on => &DEBUG_ON,
***************
*** 105,118 ****
DEBUG_DIRS DEBUG_STASH DEBUG_CONTEXT DEBUG_PARSER
DEBUG_PROVIDER DEBUG_PLUGINS DEBUG_FILTERS DEBUG_SERVICE
DEBUG_ALL DEBUG_CALLER DEBUG_FLAGS );
! @EXPORT_OK = ( @STATUS, @ERROR, @CHOMP, @DEBUG );
%EXPORT_TAGS = (
'all' => [ @EXPORT_OK ],
'status' => [ @STATUS ],
'error' => [ @ERROR ],
'chomp' => [ @CHOMP ],
'debug' => [ @DEBUG ],
);
--- 110,125 ----
DEBUG_DIRS DEBUG_STASH DEBUG_CONTEXT DEBUG_PARSER
DEBUG_PROVIDER DEBUG_PLUGINS DEBUG_FILTERS DEBUG_SERVICE
DEBUG_ALL DEBUG_CALLER DEBUG_FLAGS );
+ @PROCESS = qw( PROCESS_UNLOCALIZED PROCESS_LOCALIZED PROCESS_NEW );
! @EXPORT_OK = ( @STATUS, @ERROR, @CHOMP, @DEBUG, @PROCESS );
%EXPORT_TAGS = (
'all' => [ @EXPORT_OK ],
'status' => [ @STATUS ],
'error' => [ @ERROR ],
'chomp' => [ @CHOMP ],
'debug' => [ @DEBUG ],
+ 'process' => [ @PROCESS ],
);
--uAKRQypu60I7Lcqm
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="directive.diff"
*** Template2.orig/lib/Template/Directive.pm Thu Aug 8 07:59:15 2002
--- Template2/lib/Template/Directive.pm Thu Sep 5 09:32:18 2002
***************
*** 352,357 ****
--- 352,371 ----
#------------------------------------------------------------------------
+ # do(\@nameargs) [% DO template foo = bar %]
+ # # => [ [ $file, ... ], \@args ]
+ #------------------------------------------------------------------------
+
+ sub do {
+ my ($class, $nameargs) = @_;
+ my ($file, $args) = @$nameargs;
+ my $hash = shift @$args;
+ $file = $class->filenames($file);
+ $file .= @$hash ? ', { ' . join(', ', @$hash) . ' }' : '';
+ return "$OUTPUT \$context->do($file);";
+ }
+
+ #------------------------------------------------------------------------
# process(\@nameargs) [% PROCESS template foo = bar %]
# # => [ [ $file, ... ], \@args ]
#------------------------------------------------------------------------
--uAKRQypu60I7Lcqm
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="grammar.skel.diff"
*** Template2.orig/parser/Grammar.pm.skel Fri May 3 08:08:21 2002
--- Template2/parser/Grammar.pm.skel Thu Sep 5 09:26:17 2002
***************
*** 52,58 ****
GET CALL SET DEFAULT INSERT INCLUDE PROCESS WRAPPER BLOCK END
USE PLUGIN FILTER MACRO PERL RAWPERL TO STEP AND OR NOT DIV MOD
IF UNLESS ELSE ELSIF FOR NEXT WHILE SWITCH CASE META
! TRY THROW CATCH FINAL LAST RETURN STOP CLEAR VIEW DEBUG
);
# for historical reasons, != and == are converted to ne and eq to perform
--- 52,58 ----
GET CALL SET DEFAULT INSERT INCLUDE PROCESS WRAPPER BLOCK END
USE PLUGIN FILTER MACRO PERL RAWPERL TO STEP AND OR NOT DIV MOD
IF UNLESS ELSE ELSIF FOR NEXT WHILE SWITCH CASE META
! TRY THROW CATCH FINAL LAST RETURN STOP CLEAR VIEW DEBUG DO
);
# for historical reasons, != and == are converted to ne and eq to perform
--uAKRQypu60I7Lcqm
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="parser.diff"
*** Template2.orig/parser/Parser.yp Thu Aug 8 07:52:24 2002
--- Template2/parser/Parser.yp Thu Sep 5 09:26:04 2002
***************
*** 115,120 ****
--- 115,121 ----
| DEFAULT setlist { $factory->default($_[2]) }
| INSERT nameargs { $factory->insert($_[2]) }
| INCLUDE nameargs { $factory->include($_[2]) }
+ | DO nameargs { $factory->do($_[2]) }
| PROCESS nameargs { $factory->process($_[2]) }
| THROW nameargs { $factory->throw($_[2]) }
| RETURN { $factory->return() }
--uAKRQypu60I7Lcqm--