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