Andreas Reuleaux wrote: > So I am taking my first steps with repoze.bfg.
Hi Andreas, Thanks for trying things out. > - 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? chameleon.genshi is used because chameleon is used to get TAL. It seemed reasonable to provide Genshi bindings for it; the stock Genshi is not a dependency of repoze.bfg, so it's not included. chameleon.genshi is also maybe about 10X-15X faster than the stock Genshi implementation (as chameleon.zpt is about 10X-15X faster than the stock ZPT implementation). The way you appear to be using "Markup" is the same as how one might use "structure" in TAL. I don't know what the idiomatic way to get this from chameleon.genshi is, but it seems trivial to just pass in an escaper function e.g. "cgi.escape" rather than depending on "Markup". > 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) FTR, the "request_type=IRequest" is the default, you needn't specify it. > > > 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? As you mentioned, I'm not a fan of the pattern, but that aside, it looks fine to me given that you really want to use the original Genshi implementation. Obviously that's fine too ( see http://static.repoze.org/bfgdocs/narr/templates.html#templating-with-other-templating-languages ) so it looks like more of a solution than a problem to me! ;-) - C _______________________________________________ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev