Re: [Cheetahtemplate-discuss] Cheetah's Filtering
Brought to you by:
rtyler,
tavis_rudd
From: <an...@cp...> - 2007-01-03 00:57:53
|
On Tue, Nov 07, 2006 at 03:47:00PM -0000, Brian Bird wrote: > from Cheetah import Template > > source = """ > > #def func(x) > > $x > > #end def > > $func("a&b") > > """ > > t = Template.Template(source=source, filter="WebSafe") > > print t > > > > The output is > > a&amp;b > > > > when I would have expected: > > a&b Looks like a bug. I run in another WebSafe filtering problem with that may not be a bug but it's certainly not a feature either. The #include directive resets the filter back to the default. So this means you're not really safe by using Template.Template(..., filter='WebSafe') if you ever used the #include directive anywhere in your code. I thought that loading the template with WebSafe was enough and I can't see anything in the docs that warns about the included files having to explicitly re-arm the WebSafe filter that gets deactivated at every new #include directive. Unfortunately what I'm suggesting is a change in backwards compatibility so I'm unsure if it's allowed, but I believe this is what the filtering API was supposed to be in the first place. The current API is asking for troubles (I introduced a bug in my code because of the current API that got fixed by applying the below patch to Cheetah, so this is a real life trouble... well as much as my project is real life in the first place ;). The risk in applying this patch is having to add some #filter RawOrEncodedUnicode if you depended on this misfeature that made RawOrEncodedUnicode the filter of the included files. And yes, I also depended on it in one place but I had to add a single #filter RawOrEncodedUnicode while the other approach would have required to round all included files (many) with #filter WebSafe at the top. If I had to add #filter WebSafe all over the place to be safe, then I could give it up with filter='WebSafe' completely and only use #filter WebSafe everywhere. It's pointless to use filter='WebSafe' if it takes care of only 10% of the templates, I prefer to use the same method to arm WebSafe for all templates. Here the proposed fix: Index: src/Template.py =================================================================== RCS file: /cvsroot/cheetahtemplate/Cheetah/src/Template.py,v retrieving revision 1.182 diff -u -p -r1.182 Template.py --- src/Template.py 6 Jul 2006 23:09:04 -0000 1.182 +++ src/Template.py 3 Jan 2007 00:24:10 -0000 @@ -1525,6 +1525,10 @@ class Template(Servlet): nestedTemplateClass = compiler.compile(source=source,file=file) nestedTemplate = nestedTemplateClass(_preBuiltSearchList=self.searchList(), _globalSetVars=self._CHEETAH__globalSetVars) + # Set the inner template filters to the initial filter of the outer template: + # this is the only really safe way to use filter='WebSafe'. + nestedTemplate._CHEETAH__initialFilter = self._CHEETAH__initialFilter + nestedTemplate._CHEETAH__currentFilter = self._CHEETAH__initialFilter self._CHEETAH__cheetahIncludes[_includeID] = nestedTemplate else: if includeFrom == 'file': To reproduce use: echo \$x > y echo \#include \"y\" > x >>> from Cheetah.Template import Template >>> t = Template(file='x', filter='WebSafe') >>> t.x = '&' >>> t.respond() '&\n' Comments welcome. Thanks! |