Loading django/template/__init__.py +2 −2 Original line number Diff line number Diff line Loading @@ -59,8 +59,8 @@ from .base import (TemplateDoesNotExist, TemplateSyntaxError, # NOQA from .context import ContextPopException # NOQA # Template parts from .base import (Context, Node, NodeList, RequestContext, # NOQA StringOrigin, Template, Variable) from .base import (Context, Node, NodeList, Origin, RequestContext, # NOQA Template, Variable) # Deprecated in Django 1.8, will be removed in Django 2.0. from .base import resolve_variable # NOQA Loading django/template/base.py +26 −12 Original line number Diff line number Diff line Loading @@ -134,7 +134,15 @@ class TemplateSyntaxError(Exception): class TemplateDoesNotExist(Exception): pass """ This exception is used when template loaders are unable to find a template. The tried argument is an optional list of tuples containing (origin, status), where origin is an Origin object and status is a string with the reason the template wasn't found. """ def __init__(self, msg, tried=None): self.tried = tried or [] super(TemplateDoesNotExist, self).__init__(msg) class TemplateEncodingError(Exception): Loading @@ -157,23 +165,29 @@ class InvalidTemplateLibrary(Exception): class Origin(object): def __init__(self, name): def __init__(self, name, template_name=None, loader=None): self.name = name def reload(self): raise NotImplementedError('subclasses of Origin must provide a reload() method') self.template_name = template_name self.loader = loader def __str__(self): return self.name def __eq__(self, other): if not isinstance(other, Origin): return False class StringOrigin(Origin): def __init__(self, source): super(StringOrigin, self).__init__(UNKNOWN_SOURCE) self.source = source return ( self.name == other.name and self.loader == other.loader ) def reload(self): return self.source @property def loader_name(self): if self.loader: return '%s.%s' % ( self.loader.__module__, self.loader.__class__.__name__, ) class Template(object): Loading @@ -191,7 +205,7 @@ class Template(object): from .engine import Engine engine = Engine.get_default() if origin is None: origin = StringOrigin(template_string) origin = Origin(UNKNOWN_SOURCE) self.name = name self.origin = origin self.engine = engine Loading django/template/engine.py +18 −16 Original line number Diff line number Diff line Loading @@ -124,15 +124,25 @@ class Engine(object): raise ImproperlyConfigured( "Invalid value in template loaders configuration: %r" % loader) def find_template(self, name, dirs=None): def find_template(self, name, dirs=None, skip=None): tried = [] for loader in self.template_loaders: if loader.supports_recursion: try: source, display_name = loader(name, dirs) origin = self.make_origin(display_name, loader, name, dirs) return source, origin template = loader.get_template( name, template_dirs=dirs, skip=skip, ) return template, template.origin except TemplateDoesNotExist as e: tried.extend(e.tried) else: # RemovedInDjango21Warning: Use old api for non-recursive # loaders. try: return loader(name, dirs) except TemplateDoesNotExist: pass raise TemplateDoesNotExist(name) raise TemplateDoesNotExist(name, tried=tried) def from_string(self, template_code): """ Loading Loading @@ -234,11 +244,3 @@ class Engine(object): continue # If we get here, none of the templates could be loaded raise TemplateDoesNotExist(', '.join(not_found)) def make_origin(self, display_name, loader, name, dirs): if self.debug and display_name: # Inner import to avoid circular dependency from .loader import LoaderOrigin return LoaderOrigin(display_name, loader, name, dirs) else: return None django/template/loader.py +13 −15 Original line number Diff line number Diff line Loading @@ -4,25 +4,20 @@ from django.utils.deprecation import RemovedInDjango20Warning from . import engines from .backends.django import DjangoTemplates from .base import Origin, TemplateDoesNotExist from .base import TemplateDoesNotExist from .engine import ( _context_instance_undefined, _dictionary_undefined, _dirs_undefined, ) from .loaders import base class LoaderOrigin(Origin): def __init__(self, display_name, loader, name, dirs): super(LoaderOrigin, self).__init__(display_name) self.loader, self.loadname, self.dirs = loader, name, dirs def get_template(template_name, dirs=_dirs_undefined, using=None): """ Loads and returns a template for the given name. Raises TemplateDoesNotExist if no such template exists. """ tried = [] engines = _engine_list(using) for engine in engines: try: Loading @@ -37,10 +32,10 @@ def get_template(template_name, dirs=_dirs_undefined, using=None): stacklevel=2) else: return engine.get_template(template_name) except TemplateDoesNotExist: pass except TemplateDoesNotExist as e: tried.extend(e.tried) raise TemplateDoesNotExist(template_name) raise TemplateDoesNotExist(template_name, tried=tried) def select_template(template_name_list, dirs=_dirs_undefined, using=None): Loading @@ -51,6 +46,7 @@ def select_template(template_name_list, dirs=_dirs_undefined, using=None): Raises TemplateDoesNotExist if no such template exists. """ tried = [] engines = _engine_list(using) for template_name in template_name_list: for engine in engines: Loading @@ -66,11 +62,11 @@ def select_template(template_name_list, dirs=_dirs_undefined, using=None): stacklevel=2) else: return engine.get_template(template_name) except TemplateDoesNotExist: pass except TemplateDoesNotExist as e: tried.extend(e.tried) if template_name_list: raise TemplateDoesNotExist(', '.join(template_name_list)) raise TemplateDoesNotExist(', '.join(template_name_list), tried=tried) else: raise TemplateDoesNotExist("No template names provided") Loading @@ -96,6 +92,7 @@ def render_to_string(template_name, context=None, return template.render(context, request) else: tried = [] # Some deprecated arguments were passed - use the legacy code path for engine in _engine_list(using): try: Loading Loading @@ -126,13 +123,14 @@ def render_to_string(template_name, context=None, "Skipping template backend %s because its render_to_string " "method doesn't support the dictionary argument." % engine.name, stacklevel=2) except TemplateDoesNotExist: except TemplateDoesNotExist as e: tried.extend(e.tried) continue if template_name: if isinstance(template_name, (list, tuple)): template_name = ', '.join(template_name) raise TemplateDoesNotExist(template_name) raise TemplateDoesNotExist(template_name, tried=tried) else: raise TemplateDoesNotExist("No template names provided") Loading django/template/loader_tags.py +35 −1 Original line number Diff line number Diff line Loading @@ -82,6 +82,7 @@ class BlockNode(Node): class ExtendsNode(Node): must_be_first = True context_key = 'extends_context' def __init__(self, nodelist, parent_name, template_dirs=None): self.nodelist = nodelist Loading @@ -92,6 +93,39 @@ class ExtendsNode(Node): def __repr__(self): return '<ExtendsNode: extends %s>' % self.parent_name.token def find_template(self, template_name, context): """ This is a wrapper around engine.find_template(). A history is kept in the render_context attribute between successive extends calls and passed as the skip argument. This enables extends to work recursively without extending the same template twice. """ # RemovedInDjango21Warning: If any non-recursive loaders are installed # do a direct template lookup. If the same template name appears twice, # raise an exception to avoid system recursion. for loader in context.template.engine.template_loaders: if not loader.supports_recursion: history = context.render_context.setdefault( self.context_key, [context.template.origin.template_name], ) if template_name in history: raise ExtendsError( "Cannot extend templates recursively when using " "non-recursive template loaders", ) template = context.template.engine.get_template(template_name) history.append(template_name) return template history = context.render_context.setdefault( self.context_key, [context.template.origin], ) template, origin = context.template.engine.find_template( template_name, skip=history, ) history.append(origin) return template def get_parent(self, context): parent = self.parent_name.resolve(context) if not parent: Loading @@ -107,7 +141,7 @@ class ExtendsNode(Node): if isinstance(getattr(parent, 'template', None), Template): # parent is a django.template.backends.django.Template return parent.template return context.template.engine.get_template(parent) return self.find_template(parent, context) def render(self, context): compiled_parent = self.get_parent(context) Loading Loading
django/template/__init__.py +2 −2 Original line number Diff line number Diff line Loading @@ -59,8 +59,8 @@ from .base import (TemplateDoesNotExist, TemplateSyntaxError, # NOQA from .context import ContextPopException # NOQA # Template parts from .base import (Context, Node, NodeList, RequestContext, # NOQA StringOrigin, Template, Variable) from .base import (Context, Node, NodeList, Origin, RequestContext, # NOQA Template, Variable) # Deprecated in Django 1.8, will be removed in Django 2.0. from .base import resolve_variable # NOQA Loading
django/template/base.py +26 −12 Original line number Diff line number Diff line Loading @@ -134,7 +134,15 @@ class TemplateSyntaxError(Exception): class TemplateDoesNotExist(Exception): pass """ This exception is used when template loaders are unable to find a template. The tried argument is an optional list of tuples containing (origin, status), where origin is an Origin object and status is a string with the reason the template wasn't found. """ def __init__(self, msg, tried=None): self.tried = tried or [] super(TemplateDoesNotExist, self).__init__(msg) class TemplateEncodingError(Exception): Loading @@ -157,23 +165,29 @@ class InvalidTemplateLibrary(Exception): class Origin(object): def __init__(self, name): def __init__(self, name, template_name=None, loader=None): self.name = name def reload(self): raise NotImplementedError('subclasses of Origin must provide a reload() method') self.template_name = template_name self.loader = loader def __str__(self): return self.name def __eq__(self, other): if not isinstance(other, Origin): return False class StringOrigin(Origin): def __init__(self, source): super(StringOrigin, self).__init__(UNKNOWN_SOURCE) self.source = source return ( self.name == other.name and self.loader == other.loader ) def reload(self): return self.source @property def loader_name(self): if self.loader: return '%s.%s' % ( self.loader.__module__, self.loader.__class__.__name__, ) class Template(object): Loading @@ -191,7 +205,7 @@ class Template(object): from .engine import Engine engine = Engine.get_default() if origin is None: origin = StringOrigin(template_string) origin = Origin(UNKNOWN_SOURCE) self.name = name self.origin = origin self.engine = engine Loading
django/template/engine.py +18 −16 Original line number Diff line number Diff line Loading @@ -124,15 +124,25 @@ class Engine(object): raise ImproperlyConfigured( "Invalid value in template loaders configuration: %r" % loader) def find_template(self, name, dirs=None): def find_template(self, name, dirs=None, skip=None): tried = [] for loader in self.template_loaders: if loader.supports_recursion: try: source, display_name = loader(name, dirs) origin = self.make_origin(display_name, loader, name, dirs) return source, origin template = loader.get_template( name, template_dirs=dirs, skip=skip, ) return template, template.origin except TemplateDoesNotExist as e: tried.extend(e.tried) else: # RemovedInDjango21Warning: Use old api for non-recursive # loaders. try: return loader(name, dirs) except TemplateDoesNotExist: pass raise TemplateDoesNotExist(name) raise TemplateDoesNotExist(name, tried=tried) def from_string(self, template_code): """ Loading Loading @@ -234,11 +244,3 @@ class Engine(object): continue # If we get here, none of the templates could be loaded raise TemplateDoesNotExist(', '.join(not_found)) def make_origin(self, display_name, loader, name, dirs): if self.debug and display_name: # Inner import to avoid circular dependency from .loader import LoaderOrigin return LoaderOrigin(display_name, loader, name, dirs) else: return None
django/template/loader.py +13 −15 Original line number Diff line number Diff line Loading @@ -4,25 +4,20 @@ from django.utils.deprecation import RemovedInDjango20Warning from . import engines from .backends.django import DjangoTemplates from .base import Origin, TemplateDoesNotExist from .base import TemplateDoesNotExist from .engine import ( _context_instance_undefined, _dictionary_undefined, _dirs_undefined, ) from .loaders import base class LoaderOrigin(Origin): def __init__(self, display_name, loader, name, dirs): super(LoaderOrigin, self).__init__(display_name) self.loader, self.loadname, self.dirs = loader, name, dirs def get_template(template_name, dirs=_dirs_undefined, using=None): """ Loads and returns a template for the given name. Raises TemplateDoesNotExist if no such template exists. """ tried = [] engines = _engine_list(using) for engine in engines: try: Loading @@ -37,10 +32,10 @@ def get_template(template_name, dirs=_dirs_undefined, using=None): stacklevel=2) else: return engine.get_template(template_name) except TemplateDoesNotExist: pass except TemplateDoesNotExist as e: tried.extend(e.tried) raise TemplateDoesNotExist(template_name) raise TemplateDoesNotExist(template_name, tried=tried) def select_template(template_name_list, dirs=_dirs_undefined, using=None): Loading @@ -51,6 +46,7 @@ def select_template(template_name_list, dirs=_dirs_undefined, using=None): Raises TemplateDoesNotExist if no such template exists. """ tried = [] engines = _engine_list(using) for template_name in template_name_list: for engine in engines: Loading @@ -66,11 +62,11 @@ def select_template(template_name_list, dirs=_dirs_undefined, using=None): stacklevel=2) else: return engine.get_template(template_name) except TemplateDoesNotExist: pass except TemplateDoesNotExist as e: tried.extend(e.tried) if template_name_list: raise TemplateDoesNotExist(', '.join(template_name_list)) raise TemplateDoesNotExist(', '.join(template_name_list), tried=tried) else: raise TemplateDoesNotExist("No template names provided") Loading @@ -96,6 +92,7 @@ def render_to_string(template_name, context=None, return template.render(context, request) else: tried = [] # Some deprecated arguments were passed - use the legacy code path for engine in _engine_list(using): try: Loading Loading @@ -126,13 +123,14 @@ def render_to_string(template_name, context=None, "Skipping template backend %s because its render_to_string " "method doesn't support the dictionary argument." % engine.name, stacklevel=2) except TemplateDoesNotExist: except TemplateDoesNotExist as e: tried.extend(e.tried) continue if template_name: if isinstance(template_name, (list, tuple)): template_name = ', '.join(template_name) raise TemplateDoesNotExist(template_name) raise TemplateDoesNotExist(template_name, tried=tried) else: raise TemplateDoesNotExist("No template names provided") Loading
django/template/loader_tags.py +35 −1 Original line number Diff line number Diff line Loading @@ -82,6 +82,7 @@ class BlockNode(Node): class ExtendsNode(Node): must_be_first = True context_key = 'extends_context' def __init__(self, nodelist, parent_name, template_dirs=None): self.nodelist = nodelist Loading @@ -92,6 +93,39 @@ class ExtendsNode(Node): def __repr__(self): return '<ExtendsNode: extends %s>' % self.parent_name.token def find_template(self, template_name, context): """ This is a wrapper around engine.find_template(). A history is kept in the render_context attribute between successive extends calls and passed as the skip argument. This enables extends to work recursively without extending the same template twice. """ # RemovedInDjango21Warning: If any non-recursive loaders are installed # do a direct template lookup. If the same template name appears twice, # raise an exception to avoid system recursion. for loader in context.template.engine.template_loaders: if not loader.supports_recursion: history = context.render_context.setdefault( self.context_key, [context.template.origin.template_name], ) if template_name in history: raise ExtendsError( "Cannot extend templates recursively when using " "non-recursive template loaders", ) template = context.template.engine.get_template(template_name) history.append(template_name) return template history = context.render_context.setdefault( self.context_key, [context.template.origin], ) template, origin = context.template.engine.find_template( template_name, skip=history, ) history.append(origin) return template def get_parent(self, context): parent = self.parent_name.resolve(context) if not parent: Loading @@ -107,7 +141,7 @@ class ExtendsNode(Node): if isinstance(getattr(parent, 'template', None), Template): # parent is a django.template.backends.django.Template return parent.template return context.template.engine.get_template(parent) return self.find_template(parent, context) def render(self, context): compiled_parent = self.get_parent(context) Loading