[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