from django.template import loader, Context, RequestContext, TemplateSyntaxError
from django.http import HttpResponse
def new_renderer(template_prefix=None, always_use_requestcontext=True):
"""
Create a decorator which can be used as a shortcut to render templates to
an HttpResponse.
The decorated function must return either:
* an HttpResponse object,
* a string containing the template name (if doesn't start with '/' then
will be combined with the template_prefix) or
* a tuple comprising of:
* a string or tuple containing the template name(s),
* a dictionary to add to the Context or RequestContext and
* (optionally) a list of context processors (if given, forces use of
RequestContext).
Example usage (in a views module)::
from projectname.renderer import new_renderer
render_response = new_renderer('app_name/') # Template dir.
@render_response
app_view(request):
...
return 'app_view_template.htm', dict(object=object)
"""
def renderer(func):
def _dec(request, *args, **kwargs):
response = func(request, *args, **kwargs)
if isinstance(response, HttpResponse):
return response
elif isinstance(response, basestring):
template_name = response
namespace = {}
context_processors = None
elif isinstance(response, (tuple, list)):
len_tuple = len(response)
if len_tuple == 2:
template_name, namespace = response
context_processors = None
elif len_tuple == 3:
template_name, namespace, context_processors = response
else:
raise TemplateSyntaxError, '%s.%s function did not return a parsable tuple' % (func.__module__, func.__name__)
else:
raise TemplateSyntaxError, '%s.%s function did not provide a template name or HttpResponse object' % (func.__module__, func.__name__)
if always_use_requestcontext or context_processors is not None:
context = RequestContext(request, namespace, context_processors)
else:
context = Context(namespace)
if template_prefix:
if isinstance(template_name, (list, tuple)):
template_name = map(correct_path, template_name)
else:
template_name = correct_path(template_name)
return HttpResponse(loader.render_to_string(template_name, context_instance=context))
return _dec
def correct_path(template_name):
if template_name.startswith('/'):
return template_name[1:]
return '%s%s' % (template_prefix, template_name)
return renderer
Comments