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