Files
edx-platform/common/djangoapps/edxmako/template.py
David Ormsbee bb271e10e8 Revert "Request cache context processor output."
This reverts commit ad5cc3d5d9.

This was causing middleware errors while processing 404s.
2020-01-09 10:51:42 -05:00

103 lines
4.0 KiB
Python

# Copyright (c) 2008 Mikeal Rogers
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from django.conf import settings
from django.template import Context, engines
from mako.template import Template as MakoTemplate
from six import text_type
from . import Engines, LOOKUP
from .request_context import get_template_request_context
from .shortcuts import is_any_marketing_link_set, is_marketing_link_set, marketing_link
KEY_CSRF_TOKENS = ('csrf_token', 'csrf')
class Template(object):
"""
This bridges the gap between a Mako template and a Django template. It can
be rendered like it is a Django template because the arguments are transformed
in a way that MakoTemplate can understand.
"""
def __init__(self, *args, **kwargs):
"""Overrides base __init__ to provide django variable overrides"""
self.engine = kwargs.pop('engine', engines[Engines.MAKO])
if len(args) and isinstance(args[0], MakoTemplate):
self.mako_template = args[0]
else:
kwargs['lookup'] = LOOKUP['main']
self.mako_template = MakoTemplate(*args, **kwargs)
def render(self, context=None, request=None):
"""
This takes a render call with a context (from Django) and translates
it to a render call on the mako template.
"""
context_object = self._get_context_object(request)
context_dictionary = self._get_context_processors_output_dict(context_object)
if isinstance(context, Context):
context_dictionary.update(context.flatten())
elif context is not None:
context_dictionary.update(context)
self._add_core_context(context_dictionary)
self._evaluate_lazy_csrf_tokens(context_dictionary)
return self.mako_template.render_unicode(**context_dictionary)
@staticmethod
def _get_context_object(request):
"""
Get a Django RequestContext or Context, as appropriate for the situation.
In some tests, there might not be a current request.
"""
request_context = get_template_request_context(request)
if request_context is not None:
return request_context
else:
return Context({})
def _get_context_processors_output_dict(self, context_object):
"""
Run the context processors for the given context and get the output as a new dictionary.
"""
with context_object.bind_template(self):
return context_object.flatten()
@staticmethod
def _add_core_context(context_dictionary):
"""
Add to the given dictionary context variables which should always be
present, even when context processors aren't run during tests. Using
a context processor should almost always be preferred to adding more
variables here.
"""
context_dictionary['settings'] = settings
context_dictionary['EDX_ROOT_URL'] = settings.EDX_ROOT_URL
context_dictionary['marketing_link'] = marketing_link
context_dictionary['is_any_marketing_link_set'] = is_any_marketing_link_set
context_dictionary['is_marketing_link_set'] = is_marketing_link_set
@staticmethod
def _evaluate_lazy_csrf_tokens(context_dictionary):
"""
Evaluate any lazily-evaluated CSRF tokens in the given context.
"""
for key in KEY_CSRF_TOKENS:
if key in context_dictionary:
context_dictionary[key] = text_type(context_dictionary[key])