Created
April 5, 2012 01:31
-
-
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)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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