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 http://genshi.edgewall.org/wiki/GenshiRecipes/PyLayoutEquivalent (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): http://static.repoze.org/bfgdocs/api/template.html http://static.repoze.org/bfgdocs/#tutorials (steps 3+4) and that Chris, although the author of repoze.bfg.viewgroup is not to much in favor of this contentprovider / viewlet style http://www.plope.com/Members/chrism/repoze.bfg.viewgroup-1 http://svn.repoze.org/repoze.bfg.viewgroup/trunk/README.txt 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="http://genshi.edgewall.org/" py:strip="" > <a href="home">Home</a> <a href="bla">Bla</a> </div> ------------------------------------------------------------ in my models.py I then have an interface and a class for the navigation class INav(Interface): pass class Nav(object): implements(INav) tmplt="templates/nav.html" 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): pass class Content(object): implements(IContent) tmplt="templates/content.html" nav=Nav() main=MainA() (similar code for IMain/main=MainA()) The content template then references the nav and the main parts: -------------------- templates/content.html -------------------- <div xmlns:py="http://genshi.edgewall.org/" py:strip="" > this is from the content <div py:replace="Markup(provider('nav'))" /> <div py:replace="Markup(provider('main'))" /> </div> </div> ---------------------------------------------------------------- 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 views.py 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']) t=loader.load(tmpltfile) d={'Markup': Markup, } d.update(kw) stream = apply(t.generate, [], d) return Response(stream.render('xhtml', # encoding='utf-8', # default # doctype=XHTML11 )) from repoze.bfg.viewgroup.group import Provider @bfg_view(name='nav', request_type=IRequest, for_=IContent,) def nav_view(context, request): # print "in nav_view" nav=context.nav if hasattr(nav, 'tmplt'): return my_genshi_render_template_to_response(nav.tmplt) else: # some default... pass @bfg_view(name='main', request_type=IRequest, for_=IContent) def main_view(context, request): main=context.main # print main if hasattr(main, 'tmplt'): return my_genshi_render_template_to_response(main.tmplt) else: pass 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): content=context.content provider=Provider(content, request) if hasattr(content, 'tmplt'): return my_genshi_render_template_to_response(content.tmplt, provider=provider) 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? -Andreas _______________________________________________ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev