[Twisted-web] Sub-tag level templating in Nevow: possible?

Matt Goodall matt at pollenation.net
Sun Oct 10 14:57:26 MDT 2004

On Sun, 2004-10-10 at 21:44 +0200, Mary Gardiner wrote:
> I have a use-case for sub-tag level templating in Nevow.
> Imagine that for some reason I have a list of categories that I want to
> link to. I might want to link to them like this:
>     <a href="catname1">catname1</a>
>     <a href="catname2">catname2</a>
>     <a href="catname3">catname3</a>
> Or I might want to link to them like this:
>     <a href="catname1">Category catname1</a>
>     <a href="catname2">Category catname2</a>
>     <a href="catname3">Category catname3</a>
> As best I can tell, the only way to do this is by changing a render_
> method to be either:
>     render_atag(self, ctx, data):
>         return ctx.tag(href=data)[data]
> or
>     render_atag(self, ctx, data):
>         return ctx.tag(href=data)["Category: " + data]
> I'd prefer to specify it in an HTML template rather than the Python code for
> various reasons (for starters, it isn't "business logic", it's a design
> choice). Is there any way to do that?

Yes, this is what slots are for ...

Your template should look something like this:

        <a href="#" n:render="category"><n:attr name="href"><n:slot
        name="link"/></n:attr>Category: <n:slot name="name"/></a>

The "contract" between the HTML template and the render method is to
provide (at least) the two slots 'link' and 'name'. Your renderer should
therefore look something:

        def render_category(self, ctx, data):
            ctx.tag.fillSlots('link', data)
            ctx.tag.fillSlots('name', data)
            return ctx.tag

As you can see, the render method provides the information but has no
idea how it is used; the template expects the slots to be filled but it
can do anything it wants with the information.

You can now change the template to the following, without affecting the
renderer, if you wanted to:

        <p n:render="category">I was provided with '<n:slot
        name="link" />' as a link and '<n:slot name="name" />' as the

Judging by your example, you only need a single slot in which case just
use the same slot name in both places in the template and change the
renderer to fill only one. Note: your renderer is allowed to fill too
many slots as long as everything the template needs is provided.

Hope this helps.

Cheers, Matt

Matt Goodall <matt at pollenation.net>

More information about the Twisted-web mailing list