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
Tags:
  • nevow
  • twisted
  • python
  • programming
2005-12-21T22:45+02:00, originally published 2005-12-21T18:40+02:00