2005/12/21

render_pattern: Repeat patterns easily in Nevow templates

After render_fragment, dialtone mentioned render_pattern, that would get one or many patterns from the page and put them in the current tag. Well, that's easy to write:

def render_pattern(self, name):
    """
    Find and render a pattern.

    Example:

    <span nevow:pattern="foo">
      I'm very repetititive.
    </span>
    <ul>
      <li nevow:render="pattern foo">
        this text will get removed when rendering
      </li>
      <li nevow:render="pattern foo"/>
    </ul>
    """
    def f(ctx, data):
        doc = self.docFactory.load(ctx)
        patterns = inevow.IQ(doc).allPatterns(name)
        return ctx.tag.clear()[patterns]
    return f

Updated to adapt doc to inevow.IQ before calling allPatterns.

render_fragment: Reusable fragment embedding in Nevow templates

This Nevow renderer came up on #twisted.web. Thanks to rwall and dialtone for input.

def render_fragment(self, name):
    """
    Find and render a fragment, with optional docFactory.

    Find a fragment factory from self via attributes named
    fragment_* and replace content of current tag with said
    fragment.

    If pattern docFactory is found under this tag, pass it as
    docFactory to the fragment factory.

    Example:

    class MyFrag(rend.Fragment):
        ...

    class MyPage(rend.Page):
        fragment_foo = MyFrag
        ...

    and give MyPage a template with

    <!-- no docFactory -->
    <div nevow:render="fragment foo">
      this text will get removed when rendering
    </div>

    <!-- with docFactory -->
    <div nevow:render="fragment foo">
      this text will get removed when rendering
      <span nevow:pattern="docFactory">
        but this whole tag will be passed as docFactory to MyFrag.
      </span>
    </div>
    """
    def f(ctx, data):
        callable = getattr(self, 'fragment_%s' % name, None)
        if callable is None:
            callable = lambda ctx, *args: ctx.tag[
             "The fragment named '%s' was not found in %r." % (name, self)]
        kwargs = {}
        try:
             docFactory = ctx.tag.onePattern('docFactory')
        except stan.NodeNotFound:
             pass
        else:
             kwargs['docFactory'] = loaders.stan(docFactory)
        return ctx.tag.clear()[callable(**kwargs)]
    return f
2005-12-21T22:45:00+02:00, originally published 2005-12-21T18:40:00+02:00
2005-12-27T11:48:00+02:00, originally published 2005-12-21T19:18:00+02:00