Discussion:
patch for nested py:else directive
Eoghan Murray
2011-06-19 15:10:34 UTC
Permalink
Hi,

I've implemented a rough draft of a possible <py:else> directive,
which can be used anywhere within a <py:if>, and doesn't get rendered
unless the py:if conditional evaluates to False.
Patch below,

Eoghan


Index: genshi/template/base.py
===================================================================
--- genshi/template/base.py (revision 1165)
+++ genshi/template/base.py (working copy)
@@ -128,6 +128,7 @@
self.push = self.frames.appendleft
self._match_templates = []
self._choice_stack = []
+ self._else_stack = []

# Helper functions for use in expressions
def defined(name):
Index: genshi/template/markup.py
===================================================================
--- genshi/template/markup.py (revision 1165)
+++ genshi/template/markup.py (working copy)
@@ -51,6 +51,7 @@
('otherwise', OtherwiseDirective),
('for', ForDirective),
('if', IfDirective),
+ ('else', ElseDirective),
('choose', ChooseDirective),
('with', WithDirective),
('replace', ReplaceDirective),
Index: genshi/template/directives.py
===================================================================
--- genshi/template/directives.py (revision 1165)
+++ genshi/template/directives.py (working copy)
@@ -21,9 +21,9 @@
_ast, _parse

__all__ = ['AttrsDirective', 'ChooseDirective', 'ContentDirective',
- 'DefDirective', 'ForDirective', 'IfDirective',
'MatchDirective',
- 'OtherwiseDirective', 'ReplaceDirective',
'StripDirective',
- 'WhenDirective', 'WithDirective']
+ 'DefDirective', 'ForDirective', 'IfDirective',
'ElseDirective',
+ 'MatchDirective', 'OtherwiseDirective',
'ReplaceDirective',
+ 'StripDirective', 'WhenDirective', 'WithDirective']
__docformat__ = 'restructuredtext en'


@@ -387,6 +387,23 @@
<div>
<b>Hello</b>
</div>
+
+ If the ``py:if`` directive contains a ``py:else`` directive,
+ the contents of the else block will be output if the condition
+ evaluates to ``False``
+
+ >>> tmpl = MarkupTemplate('''<div xmlns:py="http://
genshi.edgewall.org/"
+ ... py:if="False">
+ ... Will not be output
+ ... <py:else>Will be output</py:else>
+ ... </div>''')
+ >>> print(tmpl.generate())
+ <div>
+ Will be output
+ </div>
+
+ Behavior is undefined if a ``py:else`` block exists outside a
+ ``py:if`` block.
"""
__slots__ = []

@@ -401,9 +418,38 @@
value = _eval_expr(self.expr, ctxt, vars)
if value:
return _apply_directives(stream, directives, ctxt, vars)
+ else:
+ def _generate():
+ previous = stream.next()
+ for event in stream:
+ if previous[0] == 'SUB' and isinstance(previous[1]
[0][0], ElseDirective):
+ ctxt._else_stack.append(previous[1][0][0])
+ yield previous
+ previous = event
+ return _apply_directives(_generate(), directives, ctxt,
vars)
return []


+class ElseDirective(Directive):
+ """Implementation of the ``py:else`` directive for nesting in a
parent with
+ the ``py:if`` directive.
+
+ See the documentation of the `IfDirective` for usage.
+ """
+ __slots__ = []
+
+ def __call__(self, stream, directives, ctxt, **vars):
+ info = ctxt._choice_stack and ctxt._choice_stack[-1]
+ if not info:
+ raise TemplateRuntimeError('"else" directives can only be
used '
+ 'inside an "if" directive',
+ self.filename, *(stream.next())
[2][1:])
+ if ctxt._else_stack and ctxt._else_stack[-1] is self:
+ ctxt._else_stack.pop()
+ return _apply_directives(stream, directives, ctxt, vars)
+ else:
+ return []
+
class MatchDirective(Directive):
"""Implementation of the ``py:match`` template directive.
--
You received this message because you are subscribed to the Google Groups "Genshi" group.
To post to this group, send email to ***@googlegroups.com.
To unsubscribe from this group, send email to genshi+***@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/genshi?hl=en.
Christian Boos
2011-06-19 15:27:50 UTC
Permalink
Hi,
I've implemented a rough draft of a possible<py:else> directive,
which can be used anywhere within a<py:if>, and doesn't get rendered
unless the py:if conditional evaluates to False.
Patch below,
Very nice idea, nesting the `else` within the `if` does indeed makes it
easy to verify the syntax is correct, both when authoring the template
and programmatically. I wish I would have had this idea a few years back
when suggesting it would be nice to find a way to complement the `if` by
an `else`, as the `choose` felt too heavyweight sometimes ;-)

So I'd really much like to see that enhancement land in 0.7.

-- Christian
--
You received this message because you are subscribed to the Google Groups "Genshi" group.
To post to this group, send email to ***@googlegroups.com.
To unsubscribe from this group, send email to genshi+***@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/genshi?hl=en.
Simon Cross
2011-06-19 19:30:40 UTC
Permalink
Post by Eoghan Murray
I've implemented a rough draft of a possible <py:else> directive,
which can be used anywhere within a <py:if>, and doesn't get rendered
unless the py:if conditional evaluates to False.
Patch below,
This seems like a useful feature so I've created
http://genshi.edgewall.org/ticket/431. In future please mention if you
haven't tried your patch at all. ;)

Schiavo
Simon
--
You received this message because you are subscribed to the Google Groups "Genshi" group.
To post to this group, send email to ***@googlegroups.com.
To unsubscribe from this group, send email to genshi+***@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/genshi?hl=en.
Loading...