# HG changeset patch # User cmlenz # Date 1183383208 0 # Node ID 5458a4e8814c039e8fdc9682f8f8a11e42d7bcc9 # Parent ed5a6d9e27678ae2a3a7f05c411c790f5f62c7e3 For directives used as elements, pass all attributes without a namespace to the directive class. This enables adding optional extra attributes to directives. diff --git a/genshi/template/directives.py b/genshi/template/directives.py --- 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) diff --git a/genshi/template/markup.py b/genshi/template/markup.py --- 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 = []