[Twisted-web] How to nest LiveElements? (getting a
MissingRenderMethod error)
Jean-Paul Calderone
exarkun at divmod.com
Fri Dec 1 08:20:24 CST 2006
On Fri, 1 Dec 2006 15:35:34 +0200, kgi <iacovou at gmail.com> wrote:
>
>Hi there.
>
>I've got a web app that was originally written as a bunch of LiveElements at
>the top level of a LivePage. I want to clean up this code and restructure it
>such that several of the LiveElements are more modular; this entails making
>some of the LiveElements contain other LiveElements.
>
>Now, I could have *sworn* I've done this before, but whatever I try to do now
>I get a nevow.errors.MissingRenderMethod exception.
>
>At the end of this email is a cut-down example that exhibits the behaviour.
>OuterWidget and InnerWidget are two LiveElement objects; they can both exist
>happily in the LivePage, but if you uncomment the div containing an
>innerWidget rendering directive (around line 28) you get:
>
> File "/usr/lib/python2.4/site-packages/nevow/flat/ten.py", line 70,
>in serialize
> return partialflatten(context, obj)
> File "/usr/lib/python2.4/site-packages/nevow/flat/ten.py", line 61,
>in partialflatten
> return flattener(obj, context)
> File "/usr/lib/python2.4/site-packages/nevow/flat/flatstan.py", line
>261, in DirectiveSerializer
> renderer = rendererFactory.renderer(context, original.name)
> File "/usr/lib/python2.4/site-packages/nevow/page.py", line 78, in
>renderer
> raise MissingRenderMethod(self, name)
> nevow.errors.MissingRenderMethod: (<OuterWidget object at
>0xb763482c>, 'innerWidget')
>
>Can anyone shed any light on this?
>
>There are also seemingly three styles for render methods that I've found. The
>third was kind of guessed from the documentation of nevow.page.Element; I'm
>not sure I've used it correctly, but I seem to recall reading that the
>special "render_" prefixes will be going away and replaced by a renderer()
>registration method, like the expose() method for athena callables.
All Element renderers _must_ use renderer(). All Fragment/Page renderers
_must_ use the "render_" prefix. All Athena callables _must_ use expose().
No other approach will work at all.
>
>Which is the preferred form?
>
> def render_innerWidget ( self, ctx, data ):
> elem = InnerWidget()
> elem.setFragmentParent ( self )
> return elem
>
> def render_innerWidget ( self, ctx, data ):
> elem = InnerWidget()
> elem.setFragmentParent ( self )
> return ctx.tag[f]
Either of these is usable on a Fragment or Page class. Whether you wrap
the result in ctx.tag or not depends on whether you want to preserve the
tag on which the render directive was defined.
>
> from nevow.page import renderer
> def innerWidget ( self, request, tag ):
> elem = InnerWidget()
> elem.setFragmentParent ( self )
> return elem
> renderer(items)
Like the other examples, you could return ctx.tag[elem] here. The
difference between Fragment and Element or render_* and renderer() has
no bearing on that choice.
Hope this helps,
Jean-Paul
More information about the Twisted-web
mailing list