Hi Chris,

On Thu, Oct 09, 2008 at 08:31:11PM -0400, Chris McDonough wrote:
> Andreas Reuleaux wrote:
> > So I am taking my first steps with repoze.bfg.
> 
> Hi Andreas,
> 
> Thanks for trying things out.


Well thank you for creating repoze.bfg in the first place,
by the way, why did you call it bfg? is there any meaning
to it ?

> 
> > - 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".


Thank you for the clarification and yes, you are right, I am using
Markup() like "structure" in tal - in fact I even got the idea of doing
so from looking at your tal example (I had made some experiments
before, of passing not yet rendered genshi streams in a similar
fashion, but webob.Response() wants a string, not a genshi stream,
fine with me.) - so I will try to use cgi.escapte with
chameleon.genshi, but I guess I will generally stick to using the
original genshi implementation. It is fast enough for me (although a
real comparison would be interesting) and I want to rely on a mature
package. Also I am planning to do some i18n with babel
(babel.edgewall.org) and the two should work fairly well together.


> 
> > 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! ;-)


OK, thanks,

-Andreas



> 
> - C
> 
> _______________________________________________
> Repoze-dev mailing list
> Repoze-dev@lists.repoze.org
> http://lists.repoze.org/listinfo/repoze-dev
> 
> 
> !DSPAM:48eeebfb27422107185924!
_______________________________________________
Repoze-dev mailing list
Repoze-dev@lists.repoze.org
http://lists.repoze.org/listinfo/repoze-dev

Reply via email to