changeset 552:5458a4e8814c

For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives.
author cmlenz
date Mon, 02 Jul 2007 13:33:28 +0000
parents ed5a6d9e2767
children 887bbbfa4098
files genshi/template/directives.py genshi/template/markup.py
diffstat 2 files changed, 55 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/genshi/template/directives.py
+++ b/genshi/template/directives.py
@@ -15,7 +15,7 @@
 
 import compiler
 
-from genshi.core import Attrs, QName, Stream
+from genshi.core import QName, Stream
 from genshi.path import Path
 from genshi.template.base import TemplateRuntimeError, TemplateSyntaxError, \
                                  EXPR, _apply_directives
@@ -66,7 +66,10 @@
         
         :param template: the `Template` object
         :param stream: the event stream associated with the directive
-        :param value: the argument value for the directive
+        :param value: the argument value for the directive; if the directive was
+                      specified as an element, this will be an `Attrs` instance
+                      with all specified attributes, otherwise it will be a
+                      `unicode` object with just the attribute value
         :param namespaces: a mapping of namespace URIs to prefixes
         :param pos: a ``(filename, lineno, offset)`` tuple describing the
                     location where the directive was found in the source
@@ -247,8 +250,6 @@
     """
     __slots__ = ['name', 'args', 'star_args', 'dstar_args', 'defaults']
 
-    ATTRIBUTE = 'function'
-
     def __init__(self, args, template, namespaces=None, lineno=-1, offset=-1):
         Directive.__init__(self, None, template, namespaces, lineno, offset)
         ast = _parse(args).node
@@ -274,6 +275,13 @@
         else:
             self.name = ast.name
 
+    def attach(cls, template, stream, value, namespaces, pos):
+        if type(value) is dict:
+            value = value.get('function')
+        return super(DefDirective, cls).attach(template, stream, value,
+                                               namespaces, pos)
+    attach = classmethod(attach)
+
     def __call__(self, stream, ctxt, directives):
         stream = list(stream)
 
@@ -329,8 +337,6 @@
     """
     __slots__ = ['assign', 'filename']
 
-    ATTRIBUTE = 'each'
-
     def __init__(self, value, template, namespaces=None, lineno=-1, offset=-1):
         if ' in ' not in value:
             raise TemplateSyntaxError('"in" keyword missing in "for" directive',
@@ -342,6 +348,13 @@
         Directive.__init__(self, value.strip(), template, namespaces, lineno,
                            offset)
 
+    def attach(cls, template, stream, value, namespaces, pos):
+        if type(value) is dict:
+            value = value.get('each')
+        return super(ForDirective, cls).attach(template, stream, value,
+                                               namespaces, pos)
+    attach = classmethod(attach)
+
     def __call__(self, stream, ctxt, directives):
         iterable = self.expr.evaluate(ctxt)
         if iterable is None:
@@ -380,7 +393,12 @@
     """
     __slots__ = []
 
-    ATTRIBUTE = 'test'
+    def attach(cls, template, stream, value, namespaces, pos):
+        if type(value) is dict:
+            value = value.get('test')
+        return super(IfDirective, cls).attach(template, stream, value,
+                                              namespaces, pos)
+    attach = classmethod(attach)
 
     def __call__(self, stream, ctxt, directives):
         if self.expr.evaluate(ctxt):
@@ -407,13 +425,18 @@
     """
     __slots__ = ['path', 'namespaces']
 
-    ATTRIBUTE = 'path'
-
     def __init__(self, value, template, namespaces=None, lineno=-1, offset=-1):
         Directive.__init__(self, None, template, namespaces, lineno, offset)
         self.path = Path(value, template.filepath, lineno)
         self.namespaces = namespaces or {}
 
+    def attach(cls, template, stream, value, namespaces, pos):
+        if type(value) is dict:
+            value = value.get('path')
+        return super(MatchDirective, cls).attach(template, stream, value,
+                                                 namespaces, pos)
+    attach = classmethod(attach)
+
     def __call__(self, stream, ctxt, directives):
         ctxt._match_templates.append((self.path.test(ignore_context=True),
                                       self.path, list(stream), self.namespaces,
@@ -556,7 +579,12 @@
     """
     __slots__ = ['matched', 'value']
 
-    ATTRIBUTE = 'test'
+    def attach(cls, template, stream, value, namespaces, pos):
+        if type(value) is dict:
+            value = value.get('test')
+        return super(ChooseDirective, cls).attach(template, stream, value,
+                                                  namespaces, pos)
+    attach = classmethod(attach)
 
     def __call__(self, stream, ctxt, directives):
         frame = dict({'_choose.matched': False})
@@ -576,12 +604,17 @@
     """
     __slots__ = ['filename']
 
-    ATTRIBUTE = 'test'
-
     def __init__(self, value, template, namespaces=None, lineno=-1, offset=-1):
         Directive.__init__(self, value, template, namespaces, lineno, offset)
         self.filename = template.filepath
 
+    def attach(cls, template, stream, value, namespaces, pos):
+        if type(value) is dict:
+            value = value.get('test')
+        return super(WhenDirective, cls).attach(template, stream, value,
+                                                namespaces, pos)
+    attach = classmethod(attach)
+
     def __call__(self, stream, ctxt, directives):
         matched, frame = ctxt._find('_choose.matched')
         if not frame:
@@ -649,8 +682,6 @@
     """
     __slots__ = ['vars']
 
-    ATTRIBUTE = 'vars'
-
     def __init__(self, value, template, namespaces=None, lineno=-1, offset=-1):
         Directive.__init__(self, None, template, namespaces, lineno, offset)
         self.vars = []
@@ -673,6 +704,13 @@
             raise TemplateSyntaxError(err, template.filepath, lineno,
                                       offset + (err.offset or 0))
 
+    def attach(cls, template, stream, value, namespaces, pos):
+        if type(value) is dict:
+            value = value.get('vars')
+        return super(WithDirective, cls).attach(template, stream, value,
+                                                namespaces, pos)
+    attach = classmethod(attach)
+
     def __call__(self, stream, ctxt, directives):
         frame = {}
         ctxt.push(frame)
--- a/genshi/template/markup.py
+++ b/genshi/template/markup.py
@@ -118,8 +118,9 @@
                     if cls is None:
                         raise BadDirectiveError(tag.localname, self.filepath,
                                                 pos[1])
-                    value = attrs.get(getattr(cls, 'ATTRIBUTE', None), '')
-                    directives.append((cls, value, ns_prefix.copy(), pos))
+                    args = dict([(name.localname, value) for name, value
+                                 in attrs if not name.namespace])
+                    directives.append((cls, args, ns_prefix.copy(), pos))
                     strip = True
 
                 new_attrs = []
Copyright (C) 2012-2017 Edgewall Software