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

Reply via email to