diff -r 57b4279d8c4e -r 03e267d67478 app/django/template/context.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/django/template/context.py Fri Jul 18 18:22:23 2008 +0000 @@ -0,0 +1,103 @@ +from django.conf import settings +from django.core.exceptions import ImproperlyConfigured + +_standard_context_processors = None + +class ContextPopException(Exception): + "pop() has been called more times than push()" + pass + +class Context(object): + "A stack container for variable context" + def __init__(self, dict_=None, autoescape=True): + dict_ = dict_ or {} + self.dicts = [dict_] + self.autoescape = autoescape + + def __repr__(self): + return repr(self.dicts) + + def __iter__(self): + for d in self.dicts: + yield d + + def push(self): + d = {} + self.dicts = [d] + self.dicts + return d + + def pop(self): + if len(self.dicts) == 1: + raise ContextPopException + return self.dicts.pop(0) + + def __setitem__(self, key, value): + "Set a variable in the current context" + self.dicts[0][key] = value + + def __getitem__(self, key): + "Get a variable's value, starting at the current context and going upward" + for d in self.dicts: + if key in d: + return d[key] + raise KeyError(key) + + def __delitem__(self, key): + "Delete a variable from the current context" + del self.dicts[0][key] + + def has_key(self, key): + for d in self.dicts: + if key in d: + return True + return False + + __contains__ = has_key + + def get(self, key, otherwise=None): + for d in self.dicts: + if key in d: + return d[key] + return otherwise + + def update(self, other_dict): + "Like dict.update(). Pushes an entire dictionary's keys and values onto the context." + self.dicts = [other_dict] + self.dicts + return other_dict + +# This is a function rather than module-level procedural code because we only +# want it to execute if somebody uses RequestContext. +def get_standard_processors(): + global _standard_context_processors + if _standard_context_processors is None: + processors = [] + for path in settings.TEMPLATE_CONTEXT_PROCESSORS: + i = path.rfind('.') + module, attr = path[:i], path[i+1:] + try: + mod = __import__(module, {}, {}, [attr]) + except ImportError, e: + raise ImproperlyConfigured('Error importing request processor module %s: "%s"' % (module, e)) + try: + func = getattr(mod, attr) + except AttributeError: + raise ImproperlyConfigured('Module "%s" does not define a "%s" callable request processor' % (module, attr)) + processors.append(func) + _standard_context_processors = tuple(processors) + return _standard_context_processors + +class RequestContext(Context): + """ + This subclass of template.Context automatically populates itself using + the processors defined in TEMPLATE_CONTEXT_PROCESSORS. + Additional processors can be specified as a list of callables + using the "processors" keyword argument. + """ + def __init__(self, request, dict=None, processors=None): + Context.__init__(self, dict) + if processors is None: + processors = () + else: + processors = tuple(processors) + for processor in get_standard_processors() + processors: + self.update(processor(request))