Mercurial > piecrust2
comparison piecrust/templating/jinjaengine.py @ 907:3e69f18912f5
jinja: Remove Twig compatibility, add timer, improve code.
- Add a timer for keeping track of extensions' performance.
- Use the `select_template` function from Jinja to cut down on a few lines
of code.
| author | Ludovic Chabant <ludovic@chabant.com> |
|---|---|
| date | Sun, 23 Jul 2017 08:30:47 -0700 |
| parents | 5c5b85d4f17d |
| children | 1bb704434ee2 |
comparison
equal
deleted
inserted
replaced
| 906:1c6a4d2ec16e | 907:3e69f18912f5 |
|---|---|
| 7 | 7 |
| 8 logger = logging.getLogger(__name__) | 8 logger = logging.getLogger(__name__) |
| 9 | 9 |
| 10 | 10 |
| 11 class JinjaTemplateEngine(TemplateEngine): | 11 class JinjaTemplateEngine(TemplateEngine): |
| 12 # Name `twig` is for backwards compatibility with PieCrust 1.x. | 12 ENGINE_NAMES = ['jinja', 'jinja2', 'j2'] |
| 13 ENGINE_NAMES = ['jinja', 'jinja2', 'j2', 'twig'] | 13 EXTENSIONS = ['html', 'jinja', 'jinja2', 'j2'] |
| 14 EXTENSIONS = ['html', 'jinja', 'jinja2', 'j2', 'twig'] | |
| 15 | 14 |
| 16 def __init__(self): | 15 def __init__(self): |
| 17 self.env = None | 16 self.env = None |
| 18 self._jinja_syntax_error = None | 17 self._jinja_syntax_error = None |
| 19 self._jinja_not_found = None | 18 self._jinja_not_found = None |
| 20 | 19 |
| 21 def renderSegmentPart(self, path, seg_part, data): | 20 def renderSegmentPart(self, path, seg_part, data): |
| 22 self._ensureLoaded() | |
| 23 | |
| 24 if not _string_needs_render(seg_part.content): | 21 if not _string_needs_render(seg_part.content): |
| 25 return seg_part.content | 22 return seg_part.content |
| 23 | |
| 24 self._ensureLoaded() | |
| 26 | 25 |
| 27 part_path = _make_segment_part_path(path, seg_part.offset) | 26 part_path = _make_segment_part_path(path, seg_part.offset) |
| 28 self.env.loader.segment_parts_cache[part_path] = ( | 27 self.env.loader.segment_parts_cache[part_path] = ( |
| 29 path, seg_part.content) | 28 path, seg_part.content) |
| 30 try: | 29 try: |
| 47 rel_path = os.path.relpath(path, self.app.root_dir) | 46 rel_path = os.path.relpath(path, self.app.root_dir) |
| 48 raise TemplatingError(msg, rel_path) from ex | 47 raise TemplatingError(msg, rel_path) from ex |
| 49 | 48 |
| 50 def renderFile(self, paths, data): | 49 def renderFile(self, paths, data): |
| 51 self._ensureLoaded() | 50 self._ensureLoaded() |
| 52 tpl = None | |
| 53 logger.debug("Looking for template: %s" % paths) | |
| 54 rendered_path = None | |
| 55 for p in paths: | |
| 56 try: | |
| 57 tpl = self.env.get_template(p) | |
| 58 rendered_path = p | |
| 59 break | |
| 60 except self._jinja_syntax_error as tse: | |
| 61 raise self._getTemplatingError(tse) | |
| 62 except self._jinja_not_found: | |
| 63 pass | |
| 64 | 51 |
| 65 if tpl is None: | 52 try: |
| 53 tpl = self.env.select_template(paths) | |
| 54 except self._jinja_syntax_error as tse: | |
| 55 raise self._getTemplatingError(tse) | |
| 56 except self._jinja_not_found: | |
| 66 raise TemplateNotFoundError() | 57 raise TemplateNotFoundError() |
| 67 | 58 |
| 68 try: | 59 try: |
| 69 return tpl.render(data) | 60 return tpl.render(data) |
| 70 except self._jinja_syntax_error as tse: | 61 except self._jinja_syntax_error as tse: |
| 73 raise | 64 raise |
| 74 except Exception as ex: | 65 except Exception as ex: |
| 75 if self.app.debug: | 66 if self.app.debug: |
| 76 raise | 67 raise |
| 77 msg = "Error rendering Jinja markup" | 68 msg = "Error rendering Jinja markup" |
| 78 rel_path = os.path.relpath(rendered_path, self.app.root_dir) | 69 name = getattr(tpl, 'name', '<unknown template>') |
| 79 raise TemplatingError(msg, rel_path) from ex | 70 raise TemplatingError(msg, name) from ex |
| 80 | 71 |
| 81 def _getTemplatingError(self, tse, filename=None): | 72 def _getTemplatingError(self, tse, filename=None): |
| 82 filename = tse.filename or filename | 73 filename = tse.filename or filename |
| 83 if filename and os.path.isabs(filename): | 74 if filename and os.path.isabs(filename): |
| 84 filename = os.path.relpath(filename, self.env.app.root_dir) | 75 filename = os.path.relpath(filename, self.env.app.root_dir) |
| 88 def _ensureLoaded(self): | 79 def _ensureLoaded(self): |
| 89 if self.env is not None: | 80 if self.env is not None: |
| 90 return | 81 return |
| 91 | 82 |
| 92 stats = self.app.env.stats | 83 stats = self.app.env.stats |
| 93 stats.registerTimer('JinjaTemplateEngineEnvironmentSetup', | 84 stats.registerTimer('JinjaTemplateEngine_setup', |
| 94 raise_if_registered=False) | 85 raise_if_registered=False) |
| 95 with stats.timerScope('JinjaTemplateEngineEnvironmentSetup'): | 86 stats.registerTimer('JinjaTemplateEngine_extensions', |
| 87 raise_if_registered=False) | |
| 88 with stats.timerScope('JinjaTemplateEngine_setup'): | |
| 96 self._load() | 89 self._load() |
| 97 | 90 |
| 98 def _load(self): | 91 def _load(self): |
| 99 get_config = self.app.config.get | 92 get_config = self.app.config.get |
| 100 | 93 |
| 102 ext_names = get_config('jinja/extensions', []) | 95 ext_names = get_config('jinja/extensions', []) |
| 103 if not isinstance(ext_names, list): | 96 if not isinstance(ext_names, list): |
| 104 ext_names = [ext_names] | 97 ext_names = [ext_names] |
| 105 | 98 |
| 106 # Turn on autoescape by default. | 99 # Turn on autoescape by default. |
| 107 autoescape = get_config('twig/auto_escape') | 100 autoescape = get_config('jinja/auto_escape', True) |
| 108 if autoescape is not None: | |
| 109 logger.warning("The `twig/auto_escape` setting is now called " | |
| 110 "`jinja/auto_escape`.") | |
| 111 else: | |
| 112 autoescape = get_config('jinja/auto_escape', True) | |
| 113 if autoescape: | 101 if autoescape: |
| 114 ext_names.append('autoescape') | 102 ext_names.append('autoescape') |
| 115 | 103 |
| 116 # Create the final list of extensions. | 104 # Create the final list of extensions. |
| 117 from piecrust.templating.jinja.extensions import ( | 105 from piecrust.templating.jinja.extensions import ( |
| 158 | 146 |
| 159 | 147 |
| 160 def _make_segment_part_path(path, start): | 148 def _make_segment_part_path(path, start): |
| 161 return '$part=%s:%d' % (path, start) | 149 return '$part=%s:%d' % (path, start) |
| 162 | 150 |
| 163 |
