Edgewall Software
Modify

Opened 5 years ago

Closed 4 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.

Attachments (0)

Change History (2)

comment:1 Changed 5 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 4 years ago by anonymous

  • Resolution set to fixed
  • Status changed from new to closed

Add Comment

Modify Ticket

Change Properties
Set your email in Preferences
Action
as closed The owner will remain cmlenz.
The resolution will be deleted. Next status will be 'reopened'.
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.