Sean Jamieson
sean at barriescene.com
Sat Jan 28 17:13:27 EST 2006
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 >>> >>>
|