So I am taking my first steps with repoze.bfg.
- I am posting this to both: repoze-dev and genshi:
the problem described is more repoze.bfg specific, but I am hoping to
get some feedback concerning the general idea from genshi users, too.

I prefer genshi over zpt templates, and - maybe somehow unusual 
- wanted to use them in a contentprovider / viewlet style.

I know there are other possibilities to work with templates in pure
genshi, for the most part I have been using the style suggested in

(i. e. I filled a layout template, included with xi:include at the bottom)

And I am aware that for repoze.bfg there are some others ways suggested in
the docs (zpt+xml): (steps 3+4)

and that Chris, although the author of repoze.bfg.viewgroup
is not to much in favor of this contentprovider / viewlet style

Still I like the idea of contentprovider / viewlets and I tried this
with genshi. I got something running, but only with the original
genshi, not the the chameleon.genshi package provided with repoze.bfg, 
I will explain:

For example the navigation of any of my pages is just a html snippet
(needs the genshi namespace to be rendered by genshi)

-------------------- templates/nav.html --------------------
<div xmlns:py="";
  <a href="home">Home</a>
  <a href="bla">Bla</a>

in my I then have an interface and a class for the

  class INav(Interface):

  class Nav(object):

and I can easily use this Navigation in some other
similar blocks - for example it is used
here in a Content block (besides another block: main)

  class IContent(Interface):

  class Content(object):

(similar code for IMain/main=MainA())

The content template then references the nav and the main

-------------------- templates/content.html --------------------
<div  xmlns:py="";

  this is from the content
  <div py:replace="Markup(provider('nav'))" />
  <div py:replace="Markup(provider('main'))" />


Note that I had to use Markup() here, because provider('nav') and
provider('main') are already rendered. I could find Markup() in the
original genshi.core package, but not in the chameleon.genshi
implementation. I am wondering, if Markup() could be added to
chameleon.genshi - or why chameleon.genshi was used in the first place
instead of the original genshi?

My then looks like this:

  # genshi installed with easy_install... in my virtualenv 
  from genshi.template import TemplateLoader
  from genshi.core import Markup

  # could not use this
  # from repoze.bfg.chameleon_genshi import get_template

  from webob import Response

  def my_genshi_render_template_to_response(tmpltfile, **kw):
      loader = TemplateLoader(['./myproject'])
      d={'Markup': Markup, }
      stream = apply(t.generate, [], d)
      return Response(stream.render('xhtml',
                                    # encoding='utf-8', # default
                                    # doctype=XHTML11

  from import Provider

  @bfg_view(name='nav', request_type=IRequest, for_=IContent,) 
  def nav_view(context, request):
      # print "in nav_view"
      if hasattr(nav, 'tmplt'):
          return my_genshi_render_template_to_response(nav.tmplt)
          # some default...

  @bfg_view(name='main', request_type=IRequest, for_=IContent)
  def main_view(context, request):
      # print main
      if hasattr(main, 'tmplt'):
          return my_genshi_render_template_to_response(main.tmplt)    

and so on, in the content_view (for IPage) the content
(including main and nav) is provided to the template

  @bfg_view(name='content', request_type=IRequest, for_=IPage)
  def content_view(context, request):
      provider=Provider(content, request)
      if hasattr(content, 'tmplt'):
          return my_genshi_render_template_to_response(content.tmplt,

So I had to define my own my_genshi_render_template_to_response()
function. For templates with utf-8 text I even had to use

  def MyMarkup(s):
      return Markup(s.decode('utf-8'))

and then fill the dictionnary above accordingly

  d={'Markup': MyMarkup,}

What do you think?

Repoze-dev mailing list

Reply via email to