1from __future__ import absolute_import 2import hashlib 3 4from django.template.base import Template 5try: 6 from django.template.exceptions import TemplateDoesNotExist 7except ImportError: # Django < 1.9 8 from django.template.base import TemplateDoesNotExist 9 10from django.template.loader import BaseLoader 11try: 12 from django.template.engine import Engine 13except ImportError: # Django < 1.8 14 pass 15import os 16 17from django.conf import settings 18from .compiler import Compiler 19 20from pyjade.utils import process 21# from django.template.loaders.cached import Loader 22 23 24try: 25 from django.template.loader import make_origin 26except ImportError: # Django >= 1.9 27 try: 28 from django.template import Origin 29 30 def make_origin(display_name, loader, name, dirs): 31 return Origin( 32 name=display_name, 33 template_name=name, 34 loader=loader, 35 ) 36 except ImportError: # Django 1.8.x 37 make_origin = Engine.get_default().make_origin 38 39 40class Loader(BaseLoader): 41 is_usable = True 42 43 def __init__(self, loaders): 44 self.template_cache = {} 45 self._loaders = loaders 46 self._cached_loaders = [] 47 48 try: 49 from django.template.loader import find_template_loader as _find_template_loader 50 except: 51 _find_template_loader = Engine.get_default().find_template_loader 52 self._find_template_loader = _find_template_loader 53 54 @property 55 def loaders(self): 56 # Resolve loaders on demand to avoid circular imports 57 if not self._cached_loaders: 58 # Set self._cached_loaders atomically. Otherwise, another thread 59 # could see an incomplete list. See #17303. 60 cached_loaders = [] 61 for loader in self._loaders: 62 cached_loaders.append(self._find_template_loader(loader)) 63 self._cached_loaders = cached_loaders 64 return self._cached_loaders 65 66 def find_template(self, name, dirs=None): 67 for loader in self.loaders: 68 try: 69 template, display_name = loader(name, dirs) 70 return (template, make_origin(display_name, loader, 71 name, dirs)) 72 except TemplateDoesNotExist: 73 pass 74 raise TemplateDoesNotExist(name) 75 76 def load_template_source(self, template_name, template_dirs=None): 77 for loader in self.loaders: 78 try: 79 return loader.load_template_source(template_name, 80 template_dirs) 81 except TemplateDoesNotExist: 82 pass 83 raise TemplateDoesNotExist(template_name) 84 85 def load_template(self, template_name, template_dirs=None): 86 key = template_name 87 if template_dirs: 88 # If template directories were specified, use a hash to differentiate 89 key = '-'.join([template_name, hashlib.sha1('|'.join(template_dirs)).hexdigest()]) 90 91 if settings.DEBUG or key not in self.template_cache: 92 93 if os.path.splitext(template_name)[1] in ('.jade',): 94 try: 95 source, display_name = self.load_template_source(template_name, template_dirs) 96 source = process(source,filename=template_name,compiler=Compiler) 97 origin = make_origin(display_name, self.load_template_source, template_name, template_dirs) 98 template = Template(source, origin, template_name) 99 except NotImplementedError: 100 template, origin = self.find_template(template_name, template_dirs) 101 else: 102 template, origin = self.find_template(template_name, template_dirs) 103 if not hasattr(template, 'render'): 104 try: 105 template = Template(process(source,filename=template_name,compiler=Compiler), origin, template_name) 106 except (TemplateDoesNotExist, UnboundLocalError): 107 # If compiling the template we found raises TemplateDoesNotExist, 108 # back off to returning he source and display name for the template 109 # we were asked to load. This allows for correct identification (later) 110 # of the actual template that does not exist. 111 return template, origin 112 self.template_cache[key] = template 113 return self.template_cache[key], None 114 115 # def _preprocess(self, source, name, filename=None): 116 # parser = Parser(source,filename=filename) 117 # block = parser.parse() 118 # compiler = Compiler(block) 119 # return compiler.compile().strip() 120 121 def reset(self): 122 "Empty the template cache." 123 self.template_cache.clear() 124