Placement of "self" in searchList during #include

Ben Hoyt <[email protected]> Wed, 30 Nov 2011 17:48:08 -0500
Newsgroups gmane.comp.python.cheetah
Message-ID <CAL9jXCFp3v1_h9MV_0+QbLASwoQeK30UTk8Ot4kZSs=BpHQr4Q@mail.gmail.com>
Hi Cheetah folks,

For some reason when you #include a file, Cheetah adds the new
Template instance's "self" to the end of the searchList, instead of at
the beginning (or at least above the calling template's self). This
causes rather non-intuitive behaviour when you're #def-ining a
function in an included template that's already been #def-ined in a
calling template.

This code for this is:
https://github.com/tavisrudd/cheetah/blob/master/cheetah/Template.py#L1478

As an example of when this is an issue, consider these templates:

main.tmpl
-----
#def greet(name)
Hello, $name.
#end def
$greet('Ben')
#include 'included.tmpl'
-----

included.tmpl
-----
#def greet(name)
Bye bye, $name!
#end def
$greet('Ben')
-----

You'd expect this to print out "Hello, Ben.\n\nBye bye, Ben!" but
instead it prints out "Hello, Ben.\n\nHello, Ben.", because
main.tmpl's "self" is above included.tmpl's "self" in the searchList,
so the $greet() in included.tmpl is still calling main.tmpl's greet
function.

You can work around this by explicitly calling $self.greet() in the
included template, but it's rare to use "self." in Cheetah templates
and so is easy to forget, leading to potential bugs.

So my question is, why doesn't #include add the included template's
"self" to the searchList before the calling template's "self", to give
the more natural search order? I'm tempted to change this behaviour,
but there's probably a good reason for it, so I'm hesitant.

To change it, you can replace these two lines in Template.py:

=A0 =A0 =A0 =A0 =A0 =A0 self._CHEETAH__searchList =3D list(_preBuiltSearchL=
ist)
=A0 =A0 =A0 =A0 =A0 =A0 self._CHEETAH__searchList.append(self)

with:

=A0 =A0 =A0 =A0 =A0 =A0 self._CHEETAH__searchList =3D []
=A0 =A0 =A0 =A0 =A0 =A0 selfAdded =3D False
=A0 =A0 =A0 =A0 =A0 =A0 for item in _preBuiltSearchList:
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if not selfAdded and isinstance(item, Templ=
ate):
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 self._CHEETAH__searchList.append(se=
lf)
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 selfAdded =3D True
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 self._CHEETAH__searchList.append(item)

This will place the #include template's "self" above the caller's, as
(at least we) expected.

Thanks,
Ben.

---------------------------------------------------------------------------=
---
All the data continuously generated in your IT infrastructure =

contains a definitive record of customers, application performance, =

security threats, fraudulent activity, and more. Splunk takes this =

data and makes sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-novd2d