Edgewall Software

Changeset 810


Ignore:
Timestamp:
Mar 26, 2008, 11:10:36 PM (16 years ago)
Author:
cmlenz
Message:

Match templates are now applied in a more controlled fashion: in the order they are declared in the template source, all match templates up to (and including) the matching template itself are applied to the matched content, whereas the match templates declared after the matching template are only applied to the generated content. Fixes #186. Many thanks to Matt Chaput for reporting the problem and providing a test case.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/ChangeLog

    r805 r810  
    5252 * The XHTML serializer now strips `xml:space` attributes as they are only
    5353   allowed on very few tags.
     54 * Match templates are now applied in a more controlled fashion: in the order
     55   they are declared in the template source, all match templates up to (and
     56   including) the matching template itself are applied to the matched content,
     57   whereas the match templates declared after the matching template are only
     58   applied to the generated content (ticket #186).
    5459
    5560
  • trunk/doc/upgrade.txt

    r723 r810  
    3030warned that lenient error handling may be removed completely in a
    3131future release.
     32
     33There has also been a subtle change to how ``py:match`` templates are
     34processed: in previous versions, all match templates would be applied
     35to the content generated by the matching template, and only the
     36matching template itself was applied recursively to the original
     37content. This behavior resulted in problems with many kinds of
     38recursive matching, and hence was changed for 0.5: now, all match
     39templates declared before the matching template are applied to the
     40original content, and match templates declared after the matching
     41template are applied to the generated content. This change should not
     42have any effect on most applications, but you may want to check your
     43use of match templates to make sure.
    3244
    3345
  • trunk/doc/xml-templates.txt

    r773 r810  
    322322
    323323.. _`Using XPath`: streams.html#using-xpath
     324
     325Match templates are applied both to the original markup as well to the
     326generated markup. The order in which they are applied depends on the order
     327they are declared in the template source: a match template defined after
     328another match template is applied to the output generated by the first match
     329template. The match templates basically form a pipeline.
    324330
    325331This directive can also be used as an element:
  • trunk/genshi/template/markup.py

    r766 r810  
    273273                    # corresponding to this start event is encountered
    274274                    inner = _strip(stream)
    275                     if 'match_once' not in hints \
    276                             and 'not_recursive' not in hints:
    277                         inner = self._match(inner, ctxt, [match_templates[idx]])
     275                    pre_match_templates = match_templates[:idx + 1]
     276                    if 'match_once' not in hints and 'not_recursive' in hints:
     277                        pre_match_templates.pop()
     278                    inner = self._match(inner, ctxt, pre_match_templates)
    278279                    content = list(self._include(chain([event], inner, tail),
    279280                                                 ctxt))
     
    291292                    template = _apply_directives(template, ctxt, directives)
    292293                    remaining = match_templates
    293                     if 'match_once' not in hints:
    294                         remaining = remaining[:idx] + remaining[idx + 1:]
    295294                    for event in self._match(self._exec(
    296295                                    self._eval(self._flatten(template, ctxt),
    297                                     ctxt), ctxt), ctxt, remaining):
     296                                    ctxt), ctxt), ctxt, match_templates[idx + 1:]):
    298297                        yield event
    299298
  • trunk/genshi/template/tests/directives.py

    r773 r810  
    631631          </body>
    632632        </html>""", str(tmpl.generate()))
     633
     634    def test_recursive_match_3(self):
     635        tmpl = MarkupTemplate("""<test xmlns:py="http://genshi.edgewall.org/">
     636          <py:match path="b[@type='bullet']">
     637            <bullet>${select('*|text()')}</bullet>
     638          </py:match>
     639          <py:match path="group[@type='bullet']">
     640            <ul>${select('*')}</ul>
     641          </py:match>
     642          <py:match path="b">
     643            <generic>${select('*|text()')}</generic>
     644          </py:match>
     645
     646          <b>
     647            <group type="bullet">
     648              <b type="bullet">1</b>
     649              <b type="bullet">2</b>
     650            </group>
     651          </b>
     652        </test>
     653        """)
     654        self.assertEqual("""<test>
     655            <generic>
     656            <ul><bullet>1</bullet><bullet>2</bullet></ul>
     657          </generic>
     658        </test>""", str(tmpl.generate()))
    633659
    634660    def test_not_match_self(self):
Note: See TracChangeset for help on using the changeset viewer.