Edgewall Software

Opened 13 years ago

Closed 13 years ago

#409 closed defect (fixed)

XInclude recursive templates doesn't seem to update the context

Reported by: jaraco@… Owned by: cmlenz
Priority: critical Milestone: 0.7
Component: General Version: 0.6
Keywords: Cc: jaraco@…

Description

According to the documentation, an xi:include tag should be run at the location it is found and executed within the current context of that tag. However, I find that recursive includes don't seem to get an updated context. The following example causes a 'Recursion Depth Exceeded' error when run:

base_xml = """<xml
	xmlns:py="http://genshi.edgewall.org/"
	xmlns:xi="http://www.w3.org/2001/XInclude"
	>
	<val>${str(data)}</val>
	<base py:for='data in data'>
		<xi:include href="base.xml" />
	</base>
</xml>"""

open('base.xml', 'w').write(base_xml)

import genshi
from genshi.template import TemplateLoader
loader = TemplateLoader(['.'], auto_reload=True)
tmpl = loader.load('base.xml')
res = tmpl.generate(data=['a', ['b']]).render('xhtml')
print res

I've verified that the 'data' variable is being rebound properly, but still the xinclude seems to run with the original context (or some other thing is happening to prevent it from eventually completing).

I started out with this more complicated example. My actual use case is even more complicated, but very practical. I have nested objects which sometimes behave like their parents (and thus should be rendered using the same template as their parent), but if I XInclude that template, I get an infinite recursion error.

Change History (2)

comment:1 Changed 13 years ago by anonymous

The primary example I gave isn't good - it fails because strings are iterable, not because of the XInclude issue. I found it in fact doesn't fail if ints are used.

The problem seems to only occur when there are two templates involved that include each other. Better to use this example:

base_xml = """<xml
	xmlns:py="http://genshi.edgewall.org/"
	xmlns:xi="http://www.w3.org/2001/XInclude"
	>
	<val>${str(data)}</val>
	<base py:for='datum in data'>
		<xi:include href="sub.xml" />
	</base>
</xml>"""

sub_xml = """<xml
	xmlns:py="http://genshi.edgewall.org/"
	xmlns:xi="http://www.w3.org/2001/XInclude"
	py:strip="True">
	<sub>$datum</sub>
	<py:if test="isinstance(datum, list)">
		<py:with vars="data = datum">
			<xi:include href="sub.xml" py:with="data=datum"/>
			<!--<call>Would recall with $data</call>-->
		</py:with>
	</py:if>
</xml>"""

open('base.xml', 'w').write(base_xml)
open('sub.xml', 'w').write(sub_xml)

data = ['a', ['b', ['c', 'd'], 'e']]
import genshi
from genshi.template import TemplateLoader
loader = TemplateLoader(['.'], auto_reload=True)
tmpl = loader.load('base.xml')
res = tmpl.generate(data=data).render('xhtml')
print res

comment:2 Changed 13 years ago by anonymous

  • Resolution set to fixed
  • Status changed from new to closed
Note: See TracTickets for help on using tickets.