Mercurial > genshi > mirror
comparison markup/template.py @ 31:2ab5fa60575d trunk
* More test cases for expression evaluation.
* Fixes for the new AST-based Python 2.5 evaluation.
author | cmlenz |
---|---|
date | Wed, 28 Jun 2006 18:39:05 +0000 |
parents | ab8703fa68b8 |
children | 35b9e9318fb1 |
comparison
equal
deleted
inserted
replaced
30:bcdbb7e5e4e5 | 31:2ab5fa60575d |
---|---|
163 the directive applies to. | 163 the directive applies to. |
164 | 164 |
165 Directives can be "anonymous" or "registered". Registered directives can be | 165 Directives can be "anonymous" or "registered". Registered directives can be |
166 applied by the template author using an XML attribute with the | 166 applied by the template author using an XML attribute with the |
167 corresponding name in the template. Such directives should be subclasses of | 167 corresponding name in the template. Such directives should be subclasses of |
168 this base class that can be instantiated with two parameters: `template` | 168 this base class that can be instantiated with the value of the directive |
169 is the `Template` instance, and `value` is the value of the directive | 169 attribute as parameter. |
170 attribute. | |
171 | 170 |
172 Anonymous directives are simply functions conforming to the protocol | 171 Anonymous directives are simply functions conforming to the protocol |
173 described above, and can only be applied programmatically (for example by | 172 described above, and can only be applied programmatically (for example by |
174 template filters). | 173 template filters). |
175 """ | 174 """ |
333 yield event | 332 yield event |
334 ctxt.pop() | 333 ctxt.pop() |
335 | 334 |
336 | 335 |
337 class ForDirective(Directive): | 336 class ForDirective(Directive): |
338 """Implementation of the `py:for` template directive. | 337 """Implementation of the `py:for` template directive for repeating an |
338 element based on an iterable in the context data. | |
339 | 339 |
340 >>> ctxt = Context(items=[1, 2, 3]) | 340 >>> ctxt = Context(items=[1, 2, 3]) |
341 >>> tmpl = Template('''<ul xmlns:py="http://purl.org/kid/ns#"> | 341 >>> tmpl = Template('''<ul xmlns:py="http://purl.org/kid/ns#"> |
342 ... <li py:for="item in items">${item}</li> | 342 ... <li py:for="item in items">${item}</li> |
343 ... </ul>''') | 343 ... </ul>''') |
372 return '<%s "%s in %s">' % (self.__class__.__name__, | 372 return '<%s "%s in %s">' % (self.__class__.__name__, |
373 ', '.join(self.targets), self.expr.source) | 373 ', '.join(self.targets), self.expr.source) |
374 | 374 |
375 | 375 |
376 class IfDirective(Directive): | 376 class IfDirective(Directive): |
377 """Implementation of the `py:if` template directive. | 377 """Implementation of the `py:if` template directive for conditionally |
378 excluding elements from being output. | |
378 | 379 |
379 >>> ctxt = Context(foo=True, bar='Hello') | 380 >>> ctxt = Context(foo=True, bar='Hello') |
380 >>> tmpl = Template('''<div xmlns:py="http://purl.org/kid/ns#"> | 381 >>> tmpl = Template('''<div xmlns:py="http://purl.org/kid/ns#"> |
381 ... <b py:if="foo">${bar}</b> | 382 ... <b py:if="foo">${bar}</b> |
382 ... </div>''') | 383 ... </div>''') |
469 | 470 |
470 | 471 |
471 class ReplaceDirective(Directive): | 472 class ReplaceDirective(Directive): |
472 """Implementation of the `py:replace` template directive. | 473 """Implementation of the `py:replace` template directive. |
473 | 474 |
475 This directive replaces the element with the result of evaluating the | |
476 value of the `py:replace` attribute: | |
477 | |
474 >>> ctxt = Context(bar='Bye') | 478 >>> ctxt = Context(bar='Bye') |
475 >>> tmpl = Template('''<div xmlns:py="http://purl.org/kid/ns#"> | 479 >>> tmpl = Template('''<div xmlns:py="http://purl.org/kid/ns#"> |
476 ... <span py:replace="bar">Hello</span> | 480 ... <span py:replace="bar">Hello</span> |
477 ... </div>''') | 481 ... </div>''') |
478 >>> print tmpl.generate(ctxt) | 482 >>> print tmpl.generate(ctxt) |
645 directives.append(cls(value)) | 649 directives.append(cls(value)) |
646 else: | 650 else: |
647 value = list(self._interpolate(value, *pos)) | 651 value = list(self._interpolate(value, *pos)) |
648 new_attrib.append((name, value)) | 652 new_attrib.append((name, value)) |
649 if directives: | 653 if directives: |
650 directives.sort(lambda a, b: cmp(self._dir_order.index(a.__class__), | 654 directives.sort(lambda a, b: cmp(self._dir_order.index(b.__class__), |
651 self._dir_order.index(b.__class__))) | 655 self._dir_order.index(a.__class__))) |
652 dirmap[(depth, tag)] = (directives, len(stream)) | 656 dirmap[(depth, tag)] = (directives, len(stream)) |
653 | 657 |
654 stream.append((kind, (tag, Attributes(new_attrib)), pos)) | 658 stream.append((kind, (tag, Attributes(new_attrib)), pos)) |
655 depth += 1 | 659 depth += 1 |
656 | 660 |
778 if kind is Template.SUB: | 782 if kind is Template.SUB: |
779 # This event is a list of directives and a list of | 783 # This event is a list of directives and a list of |
780 # nested events to which those directives should be | 784 # nested events to which those directives should be |
781 # applied | 785 # applied |
782 directives, substream = data | 786 directives, substream = data |
783 directives.reverse() | |
784 for directive in directives: | 787 for directive in directives: |
785 substream = directive(iter(substream), ctxt) | 788 substream = directive(iter(substream), ctxt) |
786 substream = self._match(self._eval(substream, ctxt), ctxt) | 789 substream = self._match(self._eval(substream, ctxt), ctxt) |
787 for event in self._flatten(substream, ctxt): | 790 for event in self._flatten(substream, ctxt): |
788 yield event | 791 yield event |