[Checkins] SVN: z3c.pt/trunk/ The ZPT parser now supports prefixed native attributes, e.g. <tal:foo tal:bar="" />.

Malthe Borch mborch at gmail.com
Tue Sep 9 08:57:19 EDT 2008


Log message for revision 90995:
  The ZPT parser now supports prefixed native attributes, e.g. <tal:foo tal:bar="" />.

Changed:
  U   z3c.pt/trunk/CHANGES.txt
  U   z3c.pt/trunk/src/z3c/pt/genshi.py
  U   z3c.pt/trunk/src/z3c/pt/genshi.txt
  U   z3c.pt/trunk/src/z3c/pt/testing.py
  U   z3c.pt/trunk/src/z3c/pt/translation.py
  U   z3c.pt/trunk/src/z3c/pt/zpt.py
  U   z3c.pt/trunk/src/z3c/pt/zpt.txt

-=-
Modified: z3c.pt/trunk/CHANGES.txt
===================================================================
--- z3c.pt/trunk/CHANGES.txt	2008-09-09 11:44:40 UTC (rev 90994)
+++ z3c.pt/trunk/CHANGES.txt	2008-09-09 12:57:19 UTC (rev 90995)
@@ -17,6 +17,9 @@
 
   Features
 
+- The ZPT parser now supports prefixed native attributes,
+  e.g. <tal:foo tal:bar="" />. [malthe]
+  
 - Source-code is now written to disk in debug mode. [malthe]
   
 - Custom validation error is now raised if inserted string does not

Modified: z3c.pt/trunk/src/z3c/pt/genshi.py
===================================================================
--- z3c.pt/trunk/src/z3c/pt/genshi.py	2008-09-09 11:44:40 UTC (rev 90994)
+++ z3c.pt/trunk/src/z3c/pt/genshi.py	2008-09-09 12:57:19 UTC (rev 90995)
@@ -10,8 +10,6 @@
     Implements the Genshi subset of the attribute template language.
     """
 
-    translator = expressions.python_translation
-    
     class node(translation.Node):
         @property
         def omit(self):
@@ -53,26 +51,15 @@
         def dynamic_attributes(self):
             return self.element.meta_attributes
         
-        translated_attributes = None
-        
         @property
         def static_attributes(self):
             return utils.get_attributes_from_namespace(
                 self.element, config.XHTML_NS)
 
-        translate = None
-        translation_name = None
-        translation_domain = None
-
         @property
         def macro(self):
             return self.element.py_def
 
-        use_macro = None
-        define_macro = None
-        define_slot = None
-        fill_slot = None
-
         @property
         def cdata(self):
             return self.element.meta_cdata
@@ -209,7 +196,10 @@
         utils.py_attr('strip'), lambda p: p.expression)
     xi_href = None
     xi_parse = None
-    
+
+class MetaElement(XHTMLElement, translation.MetaElement):
+    pass
+
 class PyElement(XHTMLElement):
     py_strip = utils.attribute("strip", lambda p: p.expression, u"")
     
@@ -238,7 +228,7 @@
     """ The parser implementation for Genshi templates """
     element_mapping = {
         config.XHTML_NS: {None: XHTMLElement},
-        config.META_NS: {None: XHTMLElement},
+        config.META_NS: {None: MetaElement},
         config.XI_NS: {'include': XiIncludeElement},
         config.PY_NS: {'if': PyIfElement,
                        'for': PyForElement,

Modified: z3c.pt/trunk/src/z3c/pt/genshi.txt
===================================================================
--- z3c.pt/trunk/src/z3c/pt/genshi.txt	2008-09-09 11:44:40 UTC (rev 90994)
+++ z3c.pt/trunk/src/z3c/pt/genshi.txt	2008-09-09 12:57:19 UTC (rev 90995)
@@ -326,6 +326,23 @@
       /* ]]> */
     </div>
 
+:: HTML comments
+
+  >>> print render_genshi("""\
+  ... <div xmlns="http://www.w3.org/1999/xhtml"
+  ...      xmlns:py="http://genshi.edgewall.org/">
+  ...   <!-- a comment -->
+  ...   <!-- a multi-
+  ...        line comment -->
+  ...   <!-- a comment with an ${'expression'} -->
+  ... </div>""")
+  <div xmlns="http://www.w3.org/1999/xhtml">
+    <!-- a comment -->
+    <!-- a multi-
+         line comment -->
+    <!-- a comment with an expression -->
+  </div>
+
 :: z3c.pt used to forget to output the ]; after the for loop
 
   >>> print render_genshi("""\

Modified: z3c.pt/trunk/src/z3c/pt/testing.py
===================================================================
--- z3c.pt/trunk/src/z3c/pt/testing.py	2008-09-09 11:44:40 UTC (rev 90994)
+++ z3c.pt/trunk/src/z3c/pt/testing.py	2008-09-09 12:57:19 UTC (rev 90995)
@@ -110,6 +110,9 @@
 
     xi_href = None
     xi_parse = None
+
+class MockMetaElement(MockElement, translation.MetaElement):
+    pass
     
 class MockXiElement(MockElement):
     xi_href = utils.attribute(
@@ -119,7 +122,7 @@
 class MockParser(etree.Parser):
     element_mapping = {
         config.XHTML_NS: {None: MockElement},
-        config.META_NS: {None: MockElement},
+        config.META_NS: {None: MockMetaElement},
         config.XI_NS: {None: MockXiElement}}
 
 mock_parser = MockParser()

Modified: z3c.pt/trunk/src/z3c/pt/translation.py
===================================================================
--- z3c.pt/trunk/src/z3c/pt/translation.py	2008-09-09 11:44:40 UTC (rev 90994)
+++ z3c.pt/trunk/src/z3c/pt/translation.py	2008-09-09 12:57:19 UTC (rev 90995)
@@ -1,6 +1,7 @@
 from StringIO import StringIO
 
 import generation
+import expressions
 import codegen
 import clauses
 import doctypes
@@ -22,6 +23,28 @@
     """
 
     symbols = config.SYMBOLS
+
+    translate = None
+    translation_name = None
+    translation_domain = None
+    translated_attributes = None
+    skip = None
+    cdata = None
+    omit = None
+    define = None
+    macro = None
+    use_macro = None
+    define_macro = None
+    fill_slot = None
+    define_slot = None
+    condition = None
+    repeat = None
+    content = None
+    include = None
+    format = None
+    dict_attributes = None
+    static_attributes = utils.emptydict()
+    dynamic_attributes = utils.emptydict()
     
     def __init__(self, element):
         self.element = element
@@ -320,7 +343,7 @@
         index = self.element.index(element)
 
         t = self.element.makeelement(utils.meta_attr('literal'))
-        t.attrib[utils.meta_attr('omit-tag')] = ''
+        t.attrib['omit-tag'] = ''
         t.tail = element.tail
         t.text = unicode(element)
         for child in element.getchildren():
@@ -365,12 +388,29 @@
     providing a code stream object.
     """
 
-    node = property(Node)
+    translator = expressions.python_translation
     
+    class node(Node):
+        @property
+        def omit(self):
+            if self.element.meta_omit is not None:
+                return self.element.meta_omit or True
+            if self.element.meta_replace:
+                return True
+
+        @property
+        def content(self):
+            return self.element.meta_replace
+
+    node = property(node)
+    
     def start(self, stream):
         self._stream = stream
         self.node.visit()
 
+    def update(self):
+        pass
+    
     @property
     def stream(self):
         while self is not None:
@@ -393,6 +433,40 @@
     meta_replace = utils.attribute(
         utils.meta_attr('replace'), lambda p: p.output)
 
+class MetaElement(Element):
+    meta_cdata = utils.attribute('cdata')
+    
+    meta_omit = True
+    
+    meta_attributes =  utils.attribute(
+        'attributes', lambda p: p.definitions)
+    meta_replace = utils.attribute(
+        'replace', lambda p: p.output)
+
+class NativeAttributePrefixSupport:
+    """Element mix-in which allows native attributes to appear with
+    namespace prefix.
+
+    >>> class MockElement(NativeAttributePrefixSupport):
+    ...     nsmap = {'prefix1': 'ns1'}
+    ...     prefix = 'prefix1'
+    ...     attrib = {'{ns1}attr1': '1', 'attr2': '2', '{ns2}attr3': '3'}
+
+    >>> element = MockElement()
+    >>> element.update()
+    >>> keys = utils.get_attributes_from_namespace(element, 'ns1').keys()
+    >>> tuple(sorted(keys))
+    ('attr1', 'attr2')
+    """
+    
+    def update(self):
+        namespace = self.nsmap[self.prefix]
+        for name, value in self.attrib.items():
+            if name.startswith('{%s}' % namespace):
+                del self.attrib[name]
+                name = name.split('}')[-1]
+                self.attrib[name] = value
+    
 class VariableInterpolation:
     def update(self):
         translator = self.translator
@@ -407,7 +481,7 @@
                 t = self.makeelement(utils.meta_attr('interpolation'))
                 expression = "structure " + \
                              (m.group('expression') or m.group('variable'))
-                t.attrib[utils.meta_attr('replace')] = expression
+                t.attrib['replace'] = expression
                 t.tail = text[m.end():]
                 self.insert(0, t)
                 t.update()
@@ -426,7 +500,7 @@
                 t = self.makeelement(utils.meta_attr('interpolation'))
                 expression = "structure " + \
                              (m.group('expression') or m.group('variable'))
-                t.attrib[utils.meta_attr('replace')] = expression
+                t.attrib['replace'] = expression
                 t.tail = self.tail[m.end():]
                 parent = self.getparent()
                 parent.insert(parent.index(self)+1, t)

Modified: z3c.pt/trunk/src/z3c/pt/zpt.py
===================================================================
--- z3c.pt/trunk/src/z3c/pt/zpt.py	2008-09-09 11:44:40 UTC (rev 90994)
+++ z3c.pt/trunk/src/z3c/pt/zpt.py	2008-09-09 12:57:19 UTC (rev 90995)
@@ -7,7 +7,8 @@
 import etree
 
 class ZopePageTemplateElement(
-    translation.Element, translation.VariableInterpolation):
+    translation.Element, translation.VariableInterpolation,
+    translation.NativeAttributePrefixSupport):
     """Zope Page Template element.
 
     Implements the ZPT subset of the attribute template language.
@@ -47,8 +48,6 @@
             return self.content or \
                    self.use_macro or self.translate is not None
 
-        dict_attributes = None
-
         @property
         def dynamic_attributes(self):
             return (self.element.tal_attributes or ()) + \
@@ -75,8 +74,6 @@
         def translation_domain(self):
             return self.element.i18n_domain
 
-        macro = None
-        
         @property
         def use_macro(self):
             return self.element.metal_use
@@ -101,9 +98,6 @@
         def default_expression(self):
             return self.element.tal_default_expression
 
-        include = None
-        format = None
-        
     node = property(node)
 
     @property
@@ -117,6 +111,7 @@
             interfaces.IExpressionTranslation, name=self.node.default_expression)
 
     def update(self):
+        translation.NativeAttributePrefixSupport.update(self)    
         translation.VariableInterpolation.update(self)        
 
 class XHTMLElement(ZopePageTemplateElement):
@@ -155,6 +150,9 @@
     i18n_name = utils.attribute(
         utils.i18n_attr('name'))
 
+class MetaElement(XHTMLElement, translation.MetaElement):
+    pass
+
 class TALElement(ZopePageTemplateElement):
     """TAL namespace element."""
     
@@ -201,7 +199,7 @@
     """ The parser implementation for ZPT """
     element_mapping = {
         config.XHTML_NS: {None: XHTMLElement},
-        config.META_NS: {None: XHTMLElement},
+        config.META_NS: {None: MetaElement},
         config.TAL_NS: {None: TALElement},
         config.METAL_NS: {None: METALElement}}
 

Modified: z3c.pt/trunk/src/z3c/pt/zpt.txt
===================================================================
--- z3c.pt/trunk/src/z3c/pt/zpt.txt	2008-09-09 11:44:40 UTC (rev 90994)
+++ z3c.pt/trunk/src/z3c/pt/zpt.txt	2008-09-09 12:57:19 UTC (rev 90995)
@@ -132,6 +132,7 @@
   ... <div xmlns="http://www.w3.org/1999/xhtml"
   ...      xmlns:tal="http://xml.zope.org/namespaces/tal">
   ...   <tal:example replace="'Hello World!'" />
+  ...   <tal:example tal:replace="'Hello World!'" />
   ...   <tal:div content="'Hello World!'" />
   ...   <tal:multiple repeat="i range(3)" replace="i" />
   ...   <tal:div condition="True">True</tal:div>
@@ -139,6 +140,7 @@
     <div xmlns="http://www.w3.org/1999/xhtml">
       Hello World!
       Hello World!
+      Hello World!
       0
       1
       2



More information about the Checkins mailing list