[ZPT] changing the order of operations

Jamie Heilman jamie at audible.transient.net
Tue Jul 29 17:43:16 EDT 2003


So here's a first cut, it may be naive still, but it reflects my
current direction, please let me know if you see any problems with it.

Given the markup:
<b tal:omit-tag=""
   tal:attributes="x here/trigger"><i
   tal:content="here/trigger">y</i></b>

We currently construct a TAL listing of:
('version', '1.4'),
('mode', 'html'),
('setSourceFile', '/taltest'),
('setPosition', (1, 0)),
('beginScope', {'tal:omit-tag': '', 'tal:attributes': 'x here/trigger'}),
('optTag', ('b', '', None, 0,
  [('startTag', ('b', [
    ('tal:omit-tag', '', 'tal'),
    ('tal:attributes', 'x here/trigger', 'tal'),
    ('x', None, 'insert', standard:'here/trigger', 0, None)]))],
  [('setPosition', (2, 19)),
   ('beginScope', {'tal:content': 'here/trigger'}),
   ('startTag', ('i', [('tal:content', 'here/trigger', 'tal')])),
   ('insertText', (standard:'here/trigger', [('rawtextOffset', ('y', 1))])),
   ('endScope', ()),
   ('rawtextOffset', ('</i>', 4))]
)),
('endScope', ())

Given that tal:omit-tag="" is a special case we can optimize that in
the generator, to completely ignore attributes and instead generate:
('version', '1.4'),
('mode', 'html'),
('setSourceFile', '/taltest'),
('setPosition', (1, 0)),
('beginScope', {'tal:omit-tag': '', 'tal:attributes': 'x here/trigger'}),
('optTag', ('b', '', None, 0,
  [('startTag', ('b', [
    ('tal:omit-tag', '', 'tal'),
    ('tal:attributes', 'x here/trigger', 'tal')]))],
  [('setPosition', (2, 35)),
   ('beginScope', {'tal:content': 'here/trigger'}),
   ('startTag', ('i', [('tal:content', 'here/trigger', 'tal')])),
   ('insertText', (standard:'here/trigger', [('rawtextOffset', ('y', 1))])),
   ('endScope', ()),
   ('rawtextOffset', ('</i>', 4))]
)),
('endScope', ())

Non-empty omit-tag expressions are defered till run-time.  Technically
its probably not impossible to detect other cases where the
optimization could be done in the TAL generated ("default" would be
easy to spot) but I'm thinking its probably not worth it just because
TALES is a moving target and coupling TAL and TALES too tightly seems
sorta dirty.  Anyway, the omit-tag optimizations also apply to
<tal:foo> tags which I hadn't really thought about attacking, but
they're all sort of related, so I figured why not.  Theres the issue
of i18n attributes as well, not having ever used i18n for anything I
don't really know how its used, but they seem to be deserving of the
same short-circuiting when combined with tal-omit, so I haven't made
any effort to prevent that from happening.  As for the runtime
short-circuiting I'm not particularly sold on my current technique.  I
only made the distinction in attrAction_tal which I'm not sure is the
right thing to do, and I kinda just hand off the task of actually
ignoring the attributes to attrAction with the assumption their action
will be set to 'insert' ... that may not be a valid assumption--I know
a lot more about how TAL works than I ever really wanted to now, but
I'm pretty sure I still know nowhere near what I should to be making
changes like this.

Anyway, patch is attached, I'd love some feedback.

-- 
Jamie Heilman                   http://audible.transient.net/~jamie/
"I was in love once -- a Sinclair ZX-81.  People said, "No, Holly, she's 
 not for you." She was cheap, she was stupid and she wouldn't load 
 -- well, not for me, anyway."				-Holly
-------------- next part --------------
--- lib/python/TAL/TALGenerator.py	25 Jul 2003 18:54:36 -0000      1.65
+++ taste/the/fun/TALGenerator.py	29 Jul 2003 23:36:24 -0000
@@ -650,7 +650,7 @@
         if optTag:
             todo["optional tag"] = omitTag, TALtag
             self.pushProgram()
-        if attrsubst or i18nattrs:
+        if not (TALtag or omitTag == '') and (attrsubst or i18nattrs):
             if attrsubst:
                 repldict = TALDefs.parseAttributeReplacements(attrsubst,
                                                               self.xml)
--- lib/python/TAL/TALInterpreter.py	Mon Apr  7 10:38:05 2003
+++ taste/the/fun/TALInterpreter.py	Tue Jul 29 15:35:51 2003
@@ -133,6 +133,7 @@
         if showtal == -1:
             showtal = (not tal)
         self.showtal = showtal
+        self.skipattrs = 0
         self.strictinsert = strictinsert
         self.stackLimit = stackLimit
         self.html = 0
@@ -345,7 +349,7 @@
         return 1, name, value
 
     def attrAction_tal(self, item):
-        if item[2] in ('metal', 'tal', 'xmlns', 'i18n'):
+        if self.skipattrs or item[2] in ('metal', 'tal', 'xmlns', 'i18n'):
             return self.attrAction(item)
         name, value, action = item[:3]
         ok = 1
@@ -384,7 +388,9 @@
         state = self.saveState()
         self.stream = stream = self.StringIO()
         self._stream_write = stream.write
+        self.skipattrs = 1
         self.interpret(start)
+        self.skipattrs = 0
         self.restoreOutputState(state)
         self.interpret(program)
 


More information about the ZPT mailing list