changeset 772:6aa9b14c68eb stable-0.5.x

Ported [897] back to 0.5.x branch.
author cmlenz
date Mon, 07 Jul 2008 16:41:16 +0000
parents c290dc5a6813
children fc0b70469266
files ChangeLog genshi/template/markup.py genshi/template/plugin.py genshi/template/tests/markup.py
diffstat 4 files changed, 38 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -13,6 +13,9 @@
  * Includes from templates loaded via an absolute path now include the correct
    file in nested directories as long if no search path has been configured
    (ticket #240).
+ * Unbuffered match templates could result in parts of the matched content
+   being included in the output if the match template didn't actually consume
+   it via one or more calls to the `select()` function (ticket #243).
 
 
 Version 0.5
--- a/genshi/template/markup.py
+++ b/genshi/template/markup.py
@@ -278,13 +278,11 @@
                     if 'not_buffered' not in hints:
                         content = list(content)
 
-                    if tail:
-                        for test in [mt[0] for mt in match_templates]:
-                            test(tail[0], namespaces, ctxt, updateonly=True)
-
                     # Make the select() function available in the body of the
                     # match template
+                    selected = [False]
                     def select(path):
+                        selected[0] = True
                         return Stream(content).select(path, namespaces, ctxt)
                     vars = dict(select=select)
 
@@ -300,6 +298,19 @@
                             ctxt, start=idx + 1, **vars):
                         yield event
 
+                    # If the match template did not actually call select to
+                    # consume the matched stream, the original events need to
+                    # be consumed here or they'll get appended to the output
+                    if not selected[0]:
+                        for event in content:
+                            pass
+
+                    # Let the remaining match templates know about the last
+                    # event in the matched content, so they can update their
+                    # internal state accordingly
+                    for test in [mt[0] for mt in match_templates]:
+                        test(tail[0], namespaces, ctxt, updateonly=True)
+
                     break
 
             else: # no matches
--- a/genshi/template/plugin.py
+++ b/genshi/template/plugin.py
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 #
-# Copyright (C) 2006-2007 Edgewall Software
+# Copyright (C) 2006-2008 Edgewall Software
 # Copyright (C) 2006 Matthew Good
 # All rights reserved.
 #
--- a/genshi/template/tests/markup.py
+++ b/genshi/template/tests/markup.py
@@ -712,6 +712,25 @@
             </body>
         </html>""", tmpl.generate().render())
 
+    def test_match_without_select(self):
+        # See <http://genshi.edgewall.org/ticket/243>
+        xml = ("""<html xmlns:py="http://genshi.edgewall.org/">
+          <py:match path="body" buffer="false">
+            <body>
+              This replaces the other text.
+            </body>
+          </py:match>
+          <body>
+            This gets replaced.
+          </body>
+        </html>""")
+        tmpl = MarkupTemplate(xml, filename='test.html')
+        self.assertEqual("""<html>
+            <body>
+              This replaces the other text.
+            </body>
+        </html>""", tmpl.generate().render())
+
 
 def suite():
     suite = unittest.TestSuite()
Copyright (C) 2012-2017 Edgewall Software