mirror of
https://github.com/django/django.git
synced 2025-10-28 08:06:09 +00:00
[1.8.x] Set context.template instead of context.engine while rendering.
This opens more possibilities, like accessing context.template.origin.
It also follows the chain of objects instead of following a shortcut.
Backport of 1bfcc95 from master
This commit is contained in:
@@ -202,19 +202,19 @@ class Template(object):
|
||||
|
||||
def render(self, context):
|
||||
"Display stage -- can be called many times"
|
||||
# Set engine attribute here to avoid changing the signature of either
|
||||
# Context.__init__ or Node.render. The engine is set only on the first
|
||||
# call to render. Further calls e.g. for includes don't override it.
|
||||
toplevel_render = context.engine is None
|
||||
# Set context.template to the original template -- as opposed to
|
||||
# extended or included templates -- during rendering. This may be
|
||||
# used for accessing context.template.engine.
|
||||
toplevel_render = context.template is None
|
||||
if toplevel_render:
|
||||
context.engine = self.engine
|
||||
context.template = self
|
||||
context.render_context.push()
|
||||
try:
|
||||
return self._render(context)
|
||||
finally:
|
||||
context.render_context.pop()
|
||||
if toplevel_render:
|
||||
context.engine = None
|
||||
context.template = None
|
||||
|
||||
|
||||
class Token(object):
|
||||
@@ -653,7 +653,7 @@ class FilterExpression(object):
|
||||
if ignore_failures:
|
||||
obj = None
|
||||
else:
|
||||
string_if_invalid = context.engine.string_if_invalid
|
||||
string_if_invalid = context.template.engine.string_if_invalid
|
||||
if string_if_invalid:
|
||||
if '%s' in string_if_invalid:
|
||||
return string_if_invalid % self.var
|
||||
@@ -845,7 +845,7 @@ class Variable(object):
|
||||
if getattr(current, 'do_not_call_in_templates', False):
|
||||
pass
|
||||
elif getattr(current, 'alters_data', False):
|
||||
current = context.engine.string_if_invalid
|
||||
current = context.template.engine.string_if_invalid
|
||||
else:
|
||||
try: # method call (assuming no args required)
|
||||
current = current()
|
||||
@@ -853,12 +853,12 @@ class Variable(object):
|
||||
try:
|
||||
getcallargs(current)
|
||||
except TypeError: # arguments *were* required
|
||||
current = context.engine.string_if_invalid # invalid method call
|
||||
current = context.template.engine.string_if_invalid # invalid method call
|
||||
else:
|
||||
raise
|
||||
except Exception as e:
|
||||
if getattr(e, 'silent_variable_failure', False):
|
||||
current = context.engine.string_if_invalid
|
||||
current = context.template.engine.string_if_invalid
|
||||
else:
|
||||
raise
|
||||
|
||||
@@ -1275,9 +1275,9 @@ class Library(object):
|
||||
elif isinstance(getattr(file_name, 'template', None), Template):
|
||||
t = file_name.template
|
||||
elif not isinstance(file_name, six.string_types) and is_iterable(file_name):
|
||||
t = context.engine.select_template(file_name)
|
||||
t = context.template.engine.select_template(file_name)
|
||||
else:
|
||||
t = context.engine.get_template(file_name)
|
||||
t = context.template.engine.get_template(file_name)
|
||||
self.nodelist = t.nodelist
|
||||
new_context = context.new(_dict)
|
||||
# Copy across the CSRF token, if present, because
|
||||
|
||||
@@ -123,7 +123,7 @@ class Context(BaseContext):
|
||||
"A stack container for variable context"
|
||||
def __init__(self, dict_=None, autoescape=True,
|
||||
current_app=_current_app_undefined,
|
||||
use_l10n=None, use_tz=None, engine=None):
|
||||
use_l10n=None, use_tz=None):
|
||||
if current_app is not _current_app_undefined:
|
||||
warnings.warn(
|
||||
"The current_app argument of Context is deprecated. Use "
|
||||
@@ -133,8 +133,10 @@ class Context(BaseContext):
|
||||
self._current_app = current_app
|
||||
self.use_l10n = use_l10n
|
||||
self.use_tz = use_tz
|
||||
self.engine = engine
|
||||
self.render_context = RenderContext()
|
||||
# Set to the original template during rendering -- as opposed to
|
||||
# extended or included templates
|
||||
self.template = None
|
||||
super(Context, self).__init__(dict_)
|
||||
|
||||
@property
|
||||
@@ -192,11 +194,11 @@ class RequestContext(Context):
|
||||
"""
|
||||
def __init__(self, request, dict_=None, processors=None,
|
||||
current_app=_current_app_undefined,
|
||||
use_l10n=None, use_tz=None, engine=None):
|
||||
use_l10n=None, use_tz=None):
|
||||
# current_app isn't passed here to avoid triggering the deprecation
|
||||
# warning in Context.__init__.
|
||||
super(RequestContext, self).__init__(
|
||||
dict_, use_l10n=use_l10n, use_tz=use_tz, engine=engine)
|
||||
dict_, use_l10n=use_l10n, use_tz=use_tz)
|
||||
if current_app is not _current_app_undefined:
|
||||
warnings.warn(
|
||||
"The current_app argument of RequestContext is deprecated. "
|
||||
@@ -207,23 +209,27 @@ class RequestContext(Context):
|
||||
self._processors = () if processors is None else tuple(processors)
|
||||
self._processors_index = len(self.dicts)
|
||||
self.update({}) # placeholder for context processors output
|
||||
self.engine = engine # re-run the setter in case engine is not None
|
||||
|
||||
@property
|
||||
def engine(self):
|
||||
return self._engine
|
||||
def template(self):
|
||||
return self._template
|
||||
|
||||
@engine.setter
|
||||
def engine(self, engine):
|
||||
self._engine = engine
|
||||
@template.setter
|
||||
def template(self, template):
|
||||
# Execute context processors when Template.render(self, context) sets
|
||||
# context.template = self. Until then, since the context isn't tied to
|
||||
# an engine, it has no way to know which context processors to apply.
|
||||
self._template = template
|
||||
if hasattr(self, '_processors_index'):
|
||||
if engine is None:
|
||||
if template is None:
|
||||
# Unset context processors.
|
||||
self.dicts[self._processors_index] = {}
|
||||
else:
|
||||
# Set context processors for this engine.
|
||||
processors = (template.engine.template_context_processors +
|
||||
self._processors)
|
||||
updates = {}
|
||||
for processor in engine.template_context_processors + self._processors:
|
||||
for processor in processors:
|
||||
updates.update(processor(self.request))
|
||||
self.dicts[self._processors_index] = updates
|
||||
|
||||
|
||||
@@ -211,7 +211,7 @@ class ForNode(Node):
|
||||
context[self.loopvars[0]] = item
|
||||
# In debug mode provide the source of the node which raised
|
||||
# the exception
|
||||
if context.engine.debug:
|
||||
if context.template.engine.debug:
|
||||
for node in self.nodelist_loop:
|
||||
try:
|
||||
nodelist.append(node.render(context))
|
||||
@@ -392,7 +392,7 @@ class SsiNode(Node):
|
||||
def render(self, context):
|
||||
filepath = self.filepath.resolve(context)
|
||||
|
||||
if not include_is_allowed(filepath, context.engine.allowed_include_roots):
|
||||
if not include_is_allowed(filepath, context.template.engine.allowed_include_roots):
|
||||
if settings.DEBUG:
|
||||
return "[Didn't have permission to include file]"
|
||||
else:
|
||||
@@ -404,7 +404,7 @@ class SsiNode(Node):
|
||||
output = ''
|
||||
if self.parsed:
|
||||
try:
|
||||
t = Template(output, name=filepath, engine=context.engine)
|
||||
t = Template(output, name=filepath, engine=context.template.engine)
|
||||
return t.render(context)
|
||||
except TemplateSyntaxError as e:
|
||||
if settings.DEBUG:
|
||||
|
||||
@@ -107,7 +107,7 @@ class ExtendsNode(Node):
|
||||
if isinstance(getattr(parent, 'template', None), Template):
|
||||
# parent is a django.template.backends.django.Template
|
||||
return parent.template
|
||||
return context.engine.get_template(parent)
|
||||
return context.template.engine.get_template(parent)
|
||||
|
||||
def render(self, context):
|
||||
compiled_parent = self.get_parent(context)
|
||||
@@ -148,7 +148,7 @@ class IncludeNode(Node):
|
||||
# Does this quack like a Template?
|
||||
if not callable(getattr(template, 'render', None)):
|
||||
# If not, we'll try get_template
|
||||
template = context.engine.get_template(template)
|
||||
template = context.template.engine.get_template(template)
|
||||
values = {
|
||||
name: var.resolve(context)
|
||||
for name, var in six.iteritems(self.extra_context)
|
||||
@@ -158,7 +158,7 @@ class IncludeNode(Node):
|
||||
with context.push(**values):
|
||||
return template.render(context)
|
||||
except Exception:
|
||||
if context.engine.debug:
|
||||
if context.template.engine.debug:
|
||||
raise
|
||||
return ''
|
||||
|
||||
|
||||
Reference in New Issue
Block a user