2014-11-29 07:05:56 +08:00
|
|
|
# Since this package contains a "django" module, this is required on Python 2.
|
|
|
|
from __future__ import absolute_import
|
|
|
|
|
2015-01-08 22:03:43 +08:00
|
|
|
import warnings
|
|
|
|
|
2014-11-29 07:05:56 +08:00
|
|
|
from django.conf import settings
|
|
|
|
from django.template.context import Context, RequestContext
|
2014-11-29 05:13:11 +08:00
|
|
|
from django.template.engine import _dirs_undefined, Engine
|
2015-01-08 22:03:43 +08:00
|
|
|
from django.utils.deprecation import RemovedInDjango20Warning
|
2014-11-29 07:05:56 +08:00
|
|
|
|
|
|
|
|
|
|
|
from .base import BaseEngine
|
|
|
|
|
|
|
|
|
|
|
|
class DjangoTemplates(BaseEngine):
|
|
|
|
|
|
|
|
app_dirname = 'templates'
|
|
|
|
|
|
|
|
def __init__(self, params):
|
|
|
|
params = params.copy()
|
|
|
|
options = params.pop('OPTIONS').copy()
|
|
|
|
options.setdefault('debug', settings.TEMPLATE_DEBUG)
|
|
|
|
options.setdefault('file_charset', settings.FILE_CHARSET)
|
|
|
|
super(DjangoTemplates, self).__init__(params)
|
|
|
|
self.engine = Engine(self.dirs, self.app_dirs, **options)
|
|
|
|
|
|
|
|
def from_string(self, template_code):
|
|
|
|
return Template(self.engine.from_string(template_code))
|
|
|
|
|
2014-11-29 05:13:11 +08:00
|
|
|
def get_template(self, template_name, dirs=_dirs_undefined):
|
|
|
|
return Template(self.engine.get_template(template_name, dirs))
|
2014-11-29 07:05:56 +08:00
|
|
|
|
|
|
|
|
|
|
|
class Template(object):
|
|
|
|
|
|
|
|
def __init__(self, template):
|
|
|
|
self.template = template
|
|
|
|
|
2014-11-29 05:13:11 +08:00
|
|
|
@property
|
|
|
|
def origin(self):
|
|
|
|
# TODO: define the Origin API. For now simply forwarding to the
|
|
|
|
# underlying Template preserves backwards-compatibility.
|
|
|
|
return self.template.origin
|
|
|
|
|
2014-11-29 07:05:56 +08:00
|
|
|
def render(self, context=None, request=None):
|
2015-01-08 22:03:43 +08:00
|
|
|
# A deprecation path is required here to cover the following usage:
|
|
|
|
# >>> from django.template import Context
|
|
|
|
# >>> from django.template.loader import get_template
|
|
|
|
# >>> template = get_template('hello.html')
|
|
|
|
# >>> template.render(Context({'name': 'world'}))
|
|
|
|
# In Django 1.7 get_template() returned a django.template.Template.
|
|
|
|
# In Django 1.8 it returns a django.template.backends.django.Template.
|
|
|
|
# In Django 2.0 the isinstance checks should be removed. If passing a
|
|
|
|
# Context or a RequestContext works by accident, it won't be an issue
|
|
|
|
# per se, but it won't be officially supported either.
|
|
|
|
if isinstance(context, RequestContext):
|
|
|
|
if request is not None and request is not context.request:
|
|
|
|
raise ValueError(
|
|
|
|
"render() was called with a RequestContext and a request "
|
|
|
|
"argument which refer to different requests. Make sure "
|
|
|
|
"that the context argument is a dict or at least that "
|
|
|
|
"the two arguments refer to the same request.")
|
|
|
|
warnings.warn(
|
|
|
|
"render() must be called with a dict, not a RequestContext.",
|
|
|
|
RemovedInDjango20Warning, stacklevel=2)
|
|
|
|
|
|
|
|
elif isinstance(context, Context):
|
|
|
|
warnings.warn(
|
|
|
|
"render() must be called with a dict, not a Context.",
|
|
|
|
RemovedInDjango20Warning, stacklevel=2)
|
|
|
|
|
|
|
|
else:
|
2014-11-29 05:13:11 +08:00
|
|
|
if request is None:
|
|
|
|
context = Context(context)
|
|
|
|
else:
|
2015-01-07 03:56:54 +08:00
|
|
|
# The following pattern is required to ensure values from
|
|
|
|
# context override those from template context processors.
|
|
|
|
original_context = context
|
|
|
|
context = RequestContext(request)
|
|
|
|
if original_context:
|
|
|
|
context.push(original_context)
|
|
|
|
|
2014-11-29 07:05:56 +08:00
|
|
|
return self.template.render(context)
|