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