Index: genshi/template/base.py
===================================================================
--- genshi/template/base.py	(revision 1162)
+++ 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 1162)
+++ 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 1162)
+++ 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'
 
 
@@ -378,7 +378,7 @@
 class IfDirective(Directive):
     """Implementation of the ``py:if`` template directive for conditionally
     excluding elements from being output.
-    
+
     >>> from genshi.template import MarkupTemplate
     >>> tmpl = MarkupTemplate('''<div xmlns:py="http://genshi.edgewall.org/">
     ...   <b py:if="foo">${bar}</b>
@@ -387,6 +387,21 @@
     <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())
+    Will be output
+
+    Behavior is undefined if a ``py:else`` block exists outside a
+    ``py:if`` block.
     """
     __slots__ = []
 
@@ -401,9 +416,45 @@
         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__ = ['filename']
+
+    def __init__(self, value, template, namespaces=None, lineno=-1, offset=-1):
+        Directive.__init__(self, value, template, namespaces, lineno, offset)
+        self.filename = template.filepath
+
+    def __call__(self, stream, directives, ctxt, **vars):
+        info = ctxt._else_stack and ctxt._else_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.
 
