Supported multiple template engines in get_template and select_template.
This commit changes the return type of these two functions. Instead of returning a django.template.Template they return a backend-specific Template class that must implement render(self, context).
This commit is contained in:
parent
6854998c8f
commit
4ea43ac915
|
@ -3,7 +3,7 @@ from __future__ import absolute_import
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.template.context import Context, RequestContext
|
from django.template.context import Context, RequestContext
|
||||||
from django.template.engine import Engine
|
from django.template.engine import _dirs_undefined, Engine
|
||||||
|
|
||||||
|
|
||||||
from .base import BaseEngine
|
from .base import BaseEngine
|
||||||
|
@ -24,8 +24,8 @@ class DjangoTemplates(BaseEngine):
|
||||||
def from_string(self, template_code):
|
def from_string(self, template_code):
|
||||||
return Template(self.engine.from_string(template_code))
|
return Template(self.engine.from_string(template_code))
|
||||||
|
|
||||||
def get_template(self, template_name):
|
def get_template(self, template_name, dirs=_dirs_undefined):
|
||||||
return Template(self.engine.get_template(template_name))
|
return Template(self.engine.get_template(template_name, dirs))
|
||||||
|
|
||||||
|
|
||||||
class Template(object):
|
class Template(object):
|
||||||
|
@ -33,7 +33,15 @@ class Template(object):
|
||||||
def __init__(self, template):
|
def __init__(self, template):
|
||||||
self.template = template
|
self.template = template
|
||||||
|
|
||||||
|
@property
|
||||||
|
def origin(self):
|
||||||
|
# TODO: define the Origin API. For now simply forwarding to the
|
||||||
|
# underlying Template preserves backwards-compatibility.
|
||||||
|
return self.template.origin
|
||||||
|
|
||||||
def render(self, context=None, request=None):
|
def render(self, context=None, request=None):
|
||||||
|
# TODO: require context to be a dict -- through a deprecation path?
|
||||||
|
if not isinstance(context, Context):
|
||||||
if request is None:
|
if request is None:
|
||||||
context = Context(context)
|
context = Context(context)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1266,6 +1266,8 @@ class Library(object):
|
||||||
if not getattr(self, 'nodelist', False):
|
if not getattr(self, 'nodelist', False):
|
||||||
if isinstance(file_name, Template):
|
if isinstance(file_name, Template):
|
||||||
t = file_name
|
t = file_name
|
||||||
|
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):
|
elif not isinstance(file_name, six.string_types) and is_iterable(file_name):
|
||||||
t = context.engine.select_template(file_name)
|
t = context.engine.select_template(file_name)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -2,8 +2,10 @@ import warnings
|
||||||
|
|
||||||
from django.utils.deprecation import RemovedInDjango20Warning
|
from django.utils.deprecation import RemovedInDjango20Warning
|
||||||
|
|
||||||
from .base import Origin
|
from . import engines
|
||||||
from .engine import Engine
|
from .backends.django import DjangoTemplates
|
||||||
|
from .base import Origin, TemplateDoesNotExist
|
||||||
|
from .engine import _dirs_undefined, Engine
|
||||||
|
|
||||||
|
|
||||||
class LoaderOrigin(Origin):
|
class LoaderOrigin(Origin):
|
||||||
|
@ -19,8 +21,62 @@ def find_template(*args, **kwargs):
|
||||||
return Engine.get_default().find_template(*args, **kwargs)
|
return Engine.get_default().find_template(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def get_template(*args, **kwargs):
|
def get_template(template_name, dirs=_dirs_undefined, using=None):
|
||||||
return Engine.get_default().get_template(*args, **kwargs)
|
"""
|
||||||
|
Loads and returns a template for the given name.
|
||||||
|
|
||||||
|
Raises TemplateDoesNotExist if no such template exists.
|
||||||
|
"""
|
||||||
|
engines = _engine_list(using)
|
||||||
|
for engine in engines:
|
||||||
|
try:
|
||||||
|
# This is required for deprecating the dirs argument. Simply
|
||||||
|
# return engine.get_template(template_name) in Django 2.0.
|
||||||
|
if isinstance(engine, DjangoTemplates):
|
||||||
|
return engine.get_template(template_name, dirs)
|
||||||
|
elif dirs is not _dirs_undefined:
|
||||||
|
warnings.warn(
|
||||||
|
"Skipping template backend %s because its get_template "
|
||||||
|
"method doesn't support the dirs argument." % engine.name,
|
||||||
|
stacklevel=2)
|
||||||
|
else:
|
||||||
|
return engine.get_template(template_name)
|
||||||
|
except TemplateDoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
|
raise TemplateDoesNotExist(template_name)
|
||||||
|
|
||||||
|
|
||||||
|
def select_template(template_name_list, dirs=_dirs_undefined, using=None):
|
||||||
|
"""
|
||||||
|
Loads and returns a template for one of the given names.
|
||||||
|
|
||||||
|
Tries names in order and returns the first template found.
|
||||||
|
|
||||||
|
Raises TemplateDoesNotExist if no such template exists.
|
||||||
|
"""
|
||||||
|
engines = _engine_list(using)
|
||||||
|
for template_name in template_name_list:
|
||||||
|
for engine in engines:
|
||||||
|
try:
|
||||||
|
# This is required for deprecating the dirs argument. Simply
|
||||||
|
# use engine.get_template(template_name) in Django 2.0.
|
||||||
|
if isinstance(engine, DjangoTemplates):
|
||||||
|
return engine.get_template(template_name, dirs)
|
||||||
|
elif dirs is not _dirs_undefined:
|
||||||
|
warnings.warn(
|
||||||
|
"Skipping template backend %s because its get_template "
|
||||||
|
"method doesn't support the dirs argument." % engine.name,
|
||||||
|
stacklevel=2)
|
||||||
|
else:
|
||||||
|
return engine.get_template(template_name)
|
||||||
|
except TemplateDoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if template_name_list:
|
||||||
|
raise TemplateDoesNotExist(', '.join(template_name_list))
|
||||||
|
else:
|
||||||
|
raise TemplateDoesNotExist("No template names provided")
|
||||||
|
|
||||||
|
|
||||||
def get_template_from_string(*args, **kwargs):
|
def get_template_from_string(*args, **kwargs):
|
||||||
|
@ -31,8 +87,8 @@ def render_to_string(*args, **kwargs):
|
||||||
return Engine.get_default().render_to_string(*args, **kwargs)
|
return Engine.get_default().render_to_string(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def select_template(*args, **kwargs):
|
def _engine_list(using=None):
|
||||||
return Engine.get_default().select_template(*args, **kwargs)
|
return engines.all() if using is None else [engines[using]]
|
||||||
|
|
||||||
|
|
||||||
# This line must remain at the bottom to avoid import loops.
|
# This line must remain at the bottom to avoid import loops.
|
||||||
|
|
|
@ -85,7 +85,7 @@ class TemplateLoaderTests(SimpleTestCase):
|
||||||
# We also rely on the fact the file system and app directories loaders
|
# We also rely on the fact the file system and app directories loaders
|
||||||
# both inherit the load_template method from the base Loader class, so
|
# both inherit the load_template method from the base Loader class, so
|
||||||
# we only need to test one of them.
|
# we only need to test one of them.
|
||||||
template = loader.get_template(load_name)
|
template = loader.get_template(load_name).template
|
||||||
template_name = template.nodelist[0].source[0].name
|
template_name = template.nodelist[0].source[0].name
|
||||||
self.assertTrue(template_name.endswith(load_name),
|
self.assertTrue(template_name.endswith(load_name),
|
||||||
'Template loaded by filesystem loader has incorrect name for debug page: %s' % template_name)
|
'Template loaded by filesystem loader has incorrect name for debug page: %s' % template_name)
|
||||||
|
@ -100,12 +100,12 @@ class TemplateLoaderTests(SimpleTestCase):
|
||||||
load_name = 'login.html'
|
load_name = 'login.html'
|
||||||
|
|
||||||
# Test the cached loader separately since it overrides load_template.
|
# Test the cached loader separately since it overrides load_template.
|
||||||
template = loader.get_template(load_name)
|
template = loader.get_template(load_name).template
|
||||||
template_name = template.nodelist[0].source[0].name
|
template_name = template.nodelist[0].source[0].name
|
||||||
self.assertTrue(template_name.endswith(load_name),
|
self.assertTrue(template_name.endswith(load_name),
|
||||||
'Template loaded through cached loader has incorrect name for debug page: %s' % template_name)
|
'Template loaded through cached loader has incorrect name for debug page: %s' % template_name)
|
||||||
|
|
||||||
template = loader.get_template(load_name)
|
template = loader.get_template(load_name).template
|
||||||
template_name = template.nodelist[0].source[0].name
|
template_name = template.nodelist[0].source[0].name
|
||||||
self.assertTrue(template_name.endswith(load_name),
|
self.assertTrue(template_name.endswith(load_name),
|
||||||
'Cached template loaded through cached loader has incorrect name for debug page: %s' % template_name)
|
'Cached template loaded through cached loader has incorrect name for debug page: %s' % template_name)
|
||||||
|
|
Loading…
Reference in New Issue