While evaluating the "component" special variable for something I'm working on I noticed that if a template processes another template, the first template's component variable is set to the second template's component variable afterwards. In other words, given these two templates:

one:
[% component.name %]
[% PROCESS two %]
[% component.name %]

two:
[% component.name %]

processing the first template results in:

one
two
two

when it should result in:

one
two
one

It looks like this happens in Context.pm's process function, which updates the stash with the new component before processing a new template but doesn't reset it afterwards. The attached patch to that function fixes the problem by storing the value of that variable before processing any templates and then reseting it to that value after processing is done.

Note that I eval the variable storage (i.e. eval { $component = $stash->get('component') };) to prevent template processing from failing in case the stash dies because the variable is not defined (without the eval two stash tests fail). It doesn't matter whether the variable is defined or not for our purposes, just that its value before processing other templates is the same as its value afterwards, so throwing the "value undefined" exception away when the variable isn't defined and restoring it to the undefined value afterwards should be exactly what we want.

-myk

diff -ur Template-Toolkit-2.10b/lib/Template/Context.pm Template-Toolkit-2.10b-component-fix/lib/Template/Context.pm
--- Template-Toolkit-2.10b/lib/Template/Context.pm	2003-12-02 14:42:12.000000000 +0100
+++ Template-Toolkit-2.10b-component-fix/lib/Template/Context.pm	2004-01-02 20:27:25.000000000 +0100
@@ -293,7 +293,7 @@
     my ($self, $template, $params, $localize) = @_;
     my ($trim, $blocks) = @$self{ qw( TRIM BLOCKS ) };
     my (@compiled, $name, $compiled);
-    my ($stash, $tblocks, $error, $tmpout);
+    my ($stash, $component, $tblocks, $error, $tmpout);
     my $output = '';
 
     $template = [ $template ] unless ref $template eq 'ARRAY';
@@ -318,6 +318,7 @@
     }
 
     eval {
+	eval { $component = $stash->get('component') };
 	foreach $name (@$template) {
 	    $compiled = shift @compiled;
 	    my $element = ref $compiled eq 'CODE' 
@@ -352,6 +353,7 @@
 	    }
 	    $output .= $tmpout;
 	}
+	$stash->set('component', $component);
     };
     $error = $@;
     

Reply via email to