Nicolas Lehuen
nicolas.lehuen at gmail.com
Sat Jan 28 17:15:51 EST 2006
Hi, I haven't thought about func_globals['__file__']... Nice one ! Regards, Nicolas 2006/1/28, Sean Jamieson <sean at barriescene.com>: > OK, taking your suggestions into account, here is my current version: > > import os > from kid import Template > # @template decorator > def template( path = 'templates', template=None, ctype='text/html' ): > def decor( func, path=path ): > if not os.path.isabs( path ): > path = os.path.join( os.path.dirname( > func.func_globals['__file__'] ), path ) > if template: > path = os.path.join( path, template ) > else: > path = os.path.join( path, '%s_%s.kid' % > (func.__module__.split('.')[-1], func.func_name) ) > def template_wrapper( *args, **kwargs ): > kwargs['req'].content_type = ctype > values = func( *args, **kwargs ) > return Template( file=path, **values ) > # copy func's attributes > template_wrapper.func_name = '%s(%s)' % ( > template_wrapper.func_name, func.func_name ) > template_wrapper.func_dict = func.func_dict > template_wrapper.func_doc = func.func_doc > return template_wrapper > return decor > > I also switch from the __*__ variables to func_* > > Sean > > Nicolas Lehuen wrote: > > >One last thing my decorator does is set the content-type header based > >on the template name. My templates are all named whatever.tmpl.txt or > >whatever.tmpl.html, so that : > > > >1) The templates can reside in the same directory as the controllers > >and still be denied access thanks to a regexp-based FilesMatch rule in > >the .htaccess file. > >2) The fact that controllers and decorators reside in the same > >directory simplifies path management (I don't give any relative path > >to find the template). Granted, it can be a bit of a mess for > >application with a great number of templates, so in that case I have a > >dedicated templates directory. > >2) The decorator can set the content-type based on the extension of > >the template, thanks to the standard mimetypes.guess_type function. > > > >Regards, > >Nicolas > > > >2006/1/28, Nicolas Lehuen <nicolas.lehuen at gmail.com>: > > > > > >>Hi, > >> > >>I'm using something similar with a custom-made templating system > >>(which looks a bit like Velocity). > >> > >>I have used req.filename rather than __file__ to get the path of the > >>file requested, because the decorator function is stored in a separate > >>library module, which means that __file__ always return the path to > >>the library module and not the path to the published module. > >> > >>One could also use stack inspection to get the proper path but > >>req.filename is quite reliable as far as the publisher is concerned. > >> > >>Just a small detail : you can test whether a path is absolute or > >>relative thanks to os.path.isabs, so you can only provide one path > >>parameter and let Python decide of its relativeness. > >> > >>Regards, > >>Nicolas > >> > >>2006/1/28, Sean Jamieson <sean at barriescene.com>: > >> > >> > >>>OK, so here is my decorator solution: > >>> > >>># @template decorator > >>>def template( relpath = 'templates', template=None, abspath=None ): > >>> def decor( func ): > >>> if abspath: > >>> path = abspath > >>> else: > >>> path = os.path.join( os.path.dirname( __file__ ), relpath ) > >>> if template: > >>> path = os.path.join( path, template ) > >>> else: > >>> path = os.path.join( path, '%s_%s.kid' % > >>>(func.__module__.split('.')[-1], func.func_name) ) > >>> def template_wrapper( *args, **kwargs ): > >>> kwargs['req'].content_type = 'text/html' > >>> values = func( *args, **kwargs ) > >>> return Template( file=path, **values ) > >>> # just so debug output makes sense > >>> template_wrapper.func_name = '%s(%s)' % ( > >>>template_wrapper.func_name, func.func_name ) > >>> return template_wrapper > >>> return decor > >>> > >>>@template() > >>>def index( req ): > >>> title = 'some title' > >>> message = 'Keep it simple, stupid.' > >>> return vars() > >>> > >>>... or something like that... > >>> > >>>Comments? > >>> > >>>Sean > >>> > >>> >
|