Skip to content

Instantly share code, notes, and snippets.

@yuchant
Created April 5, 2012 01:31
Show Gist options
  • Save yuchant/2307204 to your computer and use it in GitHub Desktop.
Save yuchant/2307204 to your computer and use it in GitHub Desktop.
Django template context variable injector decorator (inject variables into templates based on URL, not view)
#from django.core.urlresolvers import reverse, reverse_lazy, NoReverseMatch
# from django.utils.functional import lazy
# CONTEXT_INJECTOR_REVERSE_DEBUG = getattr(settings, 'CONTEXT_INJECTOR_REVERSE_DEBUG', False)
class TemplateContextInjectorMiddleware(object):
lazy_url_func_pairs = []
@classmethod
def add_func_pair(cls, key, func):
cls.lazy_url_func_pairs.append((key, func))
def get_context_processors(self, path):
"""
Gets a list of context processors associated with this path.
Evaluates lazy calls upon first call (reverse must be evaluated after django fully initializes)
"""
if not hasattr(self, '_url_func_pairs'):
self._url_func_pairs = {}
for proxy, func in self.lazy_url_func_pairs:
self._url_func_pairs.setdefault(unicode(proxy), []).append(func)
return self._url_func_pairs.get(path)
def process_template_response(self, request, response):
context_processors = self.get_context_processors(request.path)
if context_processors:
for function in context_processors:
new_context = function(request)
print 'Function found... injecting context', new_context
response.context_data.update(new_context)
return response
def inject_variables(url=None, reverse=None, args=None, kwargs=None):
"""
Inject variables into template response
@inject_variables(reverse_lazy('products:list', kwargs={'product_type_slug': 'ipad-case'}))
def foo(request):
return {
'products': [],
}
"""
if url and not isinstance(url, basestring):
raise Exception("First argument or url keyword must be a string (a url path)")
if not url and not reverse:
raise Exception("Must supply url or reverse keyword argument")
# this must RETURN a decorator.
def decorator_function(func):
TemplateContextInjectorMiddleware.add_func_pair(url or reverse, func)
def wrapped(*func_args, **func_kwargs):
return func(*func_args, **func_kwargs)
return wrapped
return decorator_function
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment