annotate piecrust/templating/pystacheengine.py @ 864:5c5b85d4f17d

debug: Raise Jinja template exceptions the same way in both render passes.
author Ludovic Chabant <ludovic@chabant.com>
date Thu, 08 Jun 2017 23:31:45 -0700
parents 370e74941d32
children 1bb704434ee2
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
185
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
1 import logging
440
32c7c2d219d2 performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents: 429
diff changeset
2 import collections.abc
185
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
3 from piecrust.templating.base import (
850
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
4 TemplateEngine, TemplateNotFoundError, TemplatingError)
185
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
5
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
6
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
7 logger = logging.getLogger(__name__)
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
8
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
9
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
10 class PystacheTemplateEngine(TemplateEngine):
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
11 ENGINE_NAMES = ['mustache']
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
12 EXTENSIONS = ['mustache']
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
13
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
14 def __init__(self):
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
15 self.renderer = None
850
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
16 self._not_found_error = None
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
17 self._pystache_error = None
185
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
18
454
96d363e2da4b templating: Let Jinja2 cache the parsed template for page contents.
Ludovic Chabant <ludovic@chabant.com>
parents: 440
diff changeset
19 def renderSegmentPart(self, path, seg_part, data):
185
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
20 self._ensureLoaded()
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
21 try:
454
96d363e2da4b templating: Let Jinja2 cache the parsed template for page contents.
Ludovic Chabant <ludovic@chabant.com>
parents: 440
diff changeset
22 return self.renderer.render(seg_part.content, data)
850
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
23 except self._not_found_error as ex:
185
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
24 raise TemplateNotFoundError() from ex
850
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
25 except self._pystache_error as ex:
454
96d363e2da4b templating: Let Jinja2 cache the parsed template for page contents.
Ludovic Chabant <ludovic@chabant.com>
parents: 440
diff changeset
26 raise TemplatingError(str(ex), path) from ex
185
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
27
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
28 def renderFile(self, paths, data):
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
29 self._ensureLoaded()
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
30 tpl = None
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
31 logger.debug("Looking for template: %s" % paths)
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
32 for p in paths:
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
33 if not p.endswith('.mustache'):
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
34 raise TemplatingError(
850
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
35 "The Mustache template engine only accepts template "
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
36 "filenames with a `.mustache` extension. Got: %s" %
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
37 p)
185
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
38 name = p[:-9] # strip `.mustache`
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
39 try:
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
40 tpl = self.renderer.load_template(name)
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
41 except Exception as ex:
519
9d1a89cd8146 cosmetic: Remove debug print here too.
Ludovic Chabant <ludovic@chabant.com>
parents: 454
diff changeset
42 logger.debug("Mustache error: %s" % ex)
185
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
43 pass
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
44
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
45 if tpl is None:
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
46 raise TemplateNotFoundError()
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
47
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
48 try:
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
49 return self.renderer.render(tpl, data)
850
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
50 except self._pystache_error as ex:
185
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
51 raise TemplatingError(str(ex)) from ex
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
52
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
53 def _ensureLoaded(self):
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
54 if self.renderer:
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
55 return
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
56
850
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
57 import pystache
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
58 import pystache.common
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
59
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
60 self._not_found_error = pystache.common.TemplateNotFoundError
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
61 self._pystache_error = pystache.common.PystacheError
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
62
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
63 class _WorkaroundRenderer(pystache.Renderer):
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
64 def _make_resolve_context(self):
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
65 mrc = super(_WorkaroundRenderer, self)._make_resolve_context()
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
66
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
67 def _workaround(stack, name):
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
68 # Pystache will treat anything that's not a string or
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
69 # a dict as a list. This is just plain wrong, but it will
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
70 # take a while before the project can get patches on Pypi.
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
71 res = mrc(stack, name)
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
72 if res is not None and (
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
73 res.__class__.__name__ in _knowns or
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
74 isinstance(res, collections.abc.Mapping)):
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
75 res = [res]
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
76 return res
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
77
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
78 return _workaround
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
79
429
ca5a3c970263 templating: Workaround for a bug with Pystache.
Ludovic Chabant <ludovic@chabant.com>
parents: 428
diff changeset
80 self.renderer = _WorkaroundRenderer(
850
370e74941d32 optimize: Only load some 3rd party packages when needed.
Ludovic Chabant <ludovic@chabant.com>
parents: 519
diff changeset
81 search_dirs=self.app.templates_dirs)
185
139179dc7abd render: Add support for a Mustache template engine.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
82
429
ca5a3c970263 templating: Workaround for a bug with Pystache.
Ludovic Chabant <ludovic@chabant.com>
parents: 428
diff changeset
83
ca5a3c970263 templating: Workaround for a bug with Pystache.
Ludovic Chabant <ludovic@chabant.com>
parents: 428
diff changeset
84 _knowns = ['PieCrustData', 'LazyPageConfigData', 'Paginator', 'Assetor',
ca5a3c970263 templating: Workaround for a bug with Pystache.
Ludovic Chabant <ludovic@chabant.com>
parents: 428
diff changeset
85 'PageLinkerData']