[Twisted-web] nested nevow:data?
jlb at houseofdistraction.com
Mon Aug 2 16:52:31 MDT 2004
Donovan Preston wrote:
> On Aug 2, 2004, at 1:36 PM, Jeff Bowden wrote:
>> Should it be possible to nest nevow:data declarations in a template?
>> <html nevow:data="order" nevow:render="order">
>> <head><title>Order <nevow:slot name="order_number"/></title></head>
>> <h1>Order <nevow:slot name="order_number"/></h1>
>> <ul nevow:data="order_items" nevow:render="sequence">
>> <li nevow:pattern="item" nevow:render="mapping">
>> ... slots and stuff
>> When I do this I get a big long stack trace rooted in
>> nevow/accessors.py. It works fine if I remove the outer
>> nevow:data="order" (and dummy up a static fillSlots call for
>> "order_number" in render_order). It also works if I remove the inner
>> I can work around the problem by putting the nevow:data="order"
>> declaration in multiple places but it would be handy if I didn't
>> have to. Is this a bug or is it by design?
> What type is "order"? A data directive puts that data on the context
> stack for the duration of that xml node; additional data directives
> are handled by getting an IContainer adapter around the nearest data
> on the stack. If, as I am suspecting, "order" is a rich python class,
> what you want to do is either mix in DataFactory to your order class
> and declare that it implements IContainer, or provide an IContainer
> adapter for your order class (which is probably a subclass of
> DataFactory). For example:
> class OrderContainer(DataFactory):
> def data_order_number(self, ctx, data):
> return self.original.orderNumber
> def data_order_items(self, ctx, data):
> return self.original.items
> compy.registerAdapter(OrderContainer, MyOrderClass, IContainer)
> This is by design. It's intended to work in such a way that fragments
> of template can have data pushed at them, and they can operate without
> knowledge of the context of the entire page.
> The biggest mistake people make in this area is when they do something
> like push a list onto the context and then try to access another data_
> method of the Page class. The directive will be satisfied by doing
> IContainer(theList).child(theDirective), and since the IContainer
> adapter for lists doesn't know how to handle anything except integer
> indexes, they get an exception.
> <ol n:data="someList" n:render="sequence">
> <li n:pattern="header" n:data="someOtherDirective">
> <!-- This won't work because "someList" is the topmost data on the
> stack, and thus we will get an exception instead of having our
> data_someOtherDirective method called on our Page -->
> Header here
> <li n:pattern="item" n:render="string">
> Items here
So you are saying is that a nested data directive will try to reference
the outer data directive rather than the page class? Wow, I'm glad I
asked. I wouldn't have guessed that based on the tutorial.
Is there a high-level overview or diagram somewhere of how all pieces of
Nevow fit together?
OK anyway so yeah, as you guessed, "order" is a python list and the
exception I get matches your description exactly. The
OrderContainer(DataFactory) suggestion seems like a conceptually clean
solution for my current task but it won't be quite so tidy when I go to
nest *it* inside of a more-or-less unrelated outer directive, which is
my next step. Maybe I'll make a data container that just passes through
requests to the page and wraps them in a new instance of itself before
returning them (i.e. simple nesting with no implied relationship between
inner and outer scopes).
More information about the Twisted-web