[Checkins] SVN: z3c.pt/trunk/src/z3c/pt/ - Added support for omitting rendering of HTML "toggle" attributes

Chris McDonough chrism at plope.com
Sat Sep 6 22:48:39 EDT 2008


Log message for revision 90918:
  - Added support for omitting rendering of HTML "toggle" attributes
    (option's ``selected`` and input's ``checked``) within dynamic
    attribute assignment.  If the value of the expression in the
    assignment evaluates equal to boolean False, the attribute will not
    be rendered.  If the value of the expression in the assignment
    evaluates equal to boolean True, the attribute will be rendered and
    the value of the attribute will be the value returned by the
    expression. [chrism]
  
  - Attribute assignments with an expression value that started with the
    characters ``in`` (e.g. ``info.somename``) would be rendered to the
    generated Python without the ``in`` prefix (as
    e.g. ``fo.somename``). [chrism]
  
  - When filling METAL slots (possibly with a specific version of
    libxml2, I am using 2.6.32) it was possible to cause the translator
    to attempt to add a stringtype to a NoneType (on a line that reads
    ``variable = self.symbols.slot+element.node.fill_slot`` because an
    XPath expression looking for fill-slot nodes did not work
    properly). [chrism]
  
  See also http://groups.google.com/group/z3c_pt/browse_thread/thread/8ef3ba6211e3dd52?hl=en
  
  
  

Changed:
  U   z3c.pt/trunk/src/z3c/pt/clauses.py
  U   z3c.pt/trunk/src/z3c/pt/expressions.py
  U   z3c.pt/trunk/src/z3c/pt/translation.py
  U   z3c.pt/trunk/src/z3c/pt/zpt.txt

-=-
Modified: z3c.pt/trunk/src/z3c/pt/clauses.py
===================================================================
--- z3c.pt/trunk/src/z3c/pt/clauses.py	2008-09-06 21:29:32 UTC (rev 90917)
+++ z3c.pt/trunk/src/z3c/pt/clauses.py	2008-09-07 02:48:38 UTC (rev 90918)
@@ -1,5 +1,3 @@
-from cgi import escape
-
 from z3c.pt import types
 from z3c.pt import config
 from z3c.pt import etree
@@ -117,7 +115,7 @@
 
         if value.symbol_mapping:
             stream.symbol_mapping.update(value.symbol_mapping)
-        
+
         if isinstance(value, types.template):
             value = types.value(value % symbols)
         if isinstance(value, types.value):
@@ -536,26 +534,50 @@
         for attribute, value in dynamic:
             assign = Assign(value)
             assign.begin(stream, temp)
+
+            # XXX 'toggle' attributes are attributes whose mere
+            # presence signifies to the consumer that something should
+            # happen regardless of the attribute's value ('checked' on
+            # input tags and 'selected' on option tags); an
+            # HTML-specific misfeature. Determining whether an
+            # attribute is a toggle attribute really should be
+            # conditioned on the tag being in the xhtml namespace (in
+            # case we're rendering something other than HTML) and not
+            # just rely on tag and attribute names (chrism), but let's
+            # go ahead make the 99.999% case work.
             
+            toggle = ( (self.tag == 'option' and attribute == 'selected') or
+                       (self.tag == 'input' and attribute == 'checked') )
+
             if utils.unicode_required_flag:
                 stream.write("if isinstance(%s, unicode):" % temp)
                 stream.indent()
+                if toggle:
+                    stream.write('if %s:' % temp)
+                    stream.indent()
                 stream.write("%s(' %s=\"')" % (stream.symbols.write, attribute))
                 stream.write("%s = %s.encode('utf-8')" % (stream.symbols.tmp, temp))
                 stream.escape(stream.symbols.tmp)
                 stream.write("%s(%s)" % (stream.symbols.write, stream.symbols.tmp))
                 stream.write("%s('\"')" % stream.symbols.write)
                 stream.outdent()
+                if toggle:
+                    stream.outdent()
                 stream.write("elif %s is not None:" % temp)
             else:
                 stream.write("if %s is not None:" % temp)
             stream.indent()
+            if toggle:
+                stream.write('if %s:' % temp)
+                stream.indent()
             stream.write("%s(' %s=\"')" % (stream.symbols.write, attribute))
             stream.write("%s = str(%s)" % (stream.symbols.tmp, temp))
             stream.escape(stream.symbols.tmp)
             stream.write("%s(%s)" % (stream.symbols.write, stream.symbols.tmp))
             stream.write("%s('\"')" % stream.symbols.write)
             stream.outdent()
+            if toggle:
+                stream.outdent()
             assign.end(stream)
 
         stream.restore()

Modified: z3c.pt/trunk/src/z3c/pt/expressions.py
===================================================================
--- z3c.pt/trunk/src/z3c/pt/expressions.py	2008-09-06 21:29:32 UTC (rev 90917)
+++ z3c.pt/trunk/src/z3c/pt/expressions.py	2008-09-07 02:48:38 UTC (rev 90918)
@@ -259,8 +259,8 @@
                 raise ValueError("Invalid variable definition (%s)." % string)
             elif token.startswith('='):
                 i += 1
-            elif token.startswith('in'):
-                i += 2
+            elif token.startswith('in '):
+                i += 3
 
             try:
                 expr = self.expression(string[i:])

Modified: z3c.pt/trunk/src/z3c/pt/translation.py
===================================================================
--- z3c.pt/trunk/src/z3c/pt/translation.py	2008-09-06 21:29:32 UTC (rev 90917)
+++ z3c.pt/trunk/src/z3c/pt/translation.py	2008-09-07 02:48:38 UTC (rev 90918)
@@ -223,6 +223,15 @@
             kwargs = []
             for element in self.element.xpath(
                 './/*[@metal:fill-slot]', namespaces={'metal': config.METAL_NS}):
+                if element.node.fill_slot is None:
+                    # XXX this should not be necessary, but the above
+                    # xpath expression finds non-"metal:fill-slot"
+                    # nodes somehow on my system; this is perhaps due
+                    # to a bug in the libxml2 version I'm using; we
+                    # work around it by just skipping the element.
+                    # (chrism)
+                    continue
+
                 variable = self.symbols.slot+element.node.fill_slot
                 kwargs.append((variable, variable))
                 

Modified: z3c.pt/trunk/src/z3c/pt/zpt.txt
===================================================================
--- z3c.pt/trunk/src/z3c/pt/zpt.txt	2008-09-06 21:29:32 UTC (rev 90917)
+++ z3c.pt/trunk/src/z3c/pt/zpt.txt	2008-09-07 02:48:38 UTC (rev 90918)
@@ -38,6 +38,23 @@
       <span></span>
     </div>
 
+tal:attributes 'checked' and 'selected' toggles
+
+  >>> print render_zpt("""\
+  ... <div xmlns="http://www.w3.org/1999/xhtml"
+  ...      xmlns:tal="http://xml.zope.org/namespaces/tal">
+  ...   <option tal:attributes="selected True"/>
+  ...   <option tal:attributes="selected False"/>
+  ...   <input tal:attributes="checked True"/>
+  ...   <input tal:attributes="checked False"/>
+  ... </div>""")
+    <div xmlns="http://www.w3.org/1999/xhtml">
+       <option selected="True" />
+       <option />
+       <input checked="True" />
+       <input />
+    </div>
+
 tal:repeat
     
   >>> print render_zpt("""\



More information about the Checkins mailing list