Mercurial > piecrust2
view piecrust/templating/pystacheengine.py @ 661:2f780b191541
internal: Fix a bug with registering taxonomy terms that are not strings.
Some objects, like the blog data provider's taxnonomy entries, can render as
strings, but are objects themselves. When registering them as "used terms", we
need to use their string representation.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Tue, 01 Mar 2016 22:26:09 -0800 |
parents | 9d1a89cd8146 |
children | 370e74941d32 |
line wrap: on
line source
import logging import collections.abc import pystache import pystache.common from piecrust.templating.base import ( TemplateEngine, TemplateNotFoundError, TemplatingError) logger = logging.getLogger(__name__) class PystacheTemplateEngine(TemplateEngine): ENGINE_NAMES = ['mustache'] EXTENSIONS = ['mustache'] def __init__(self): self.renderer = None def renderSegmentPart(self, path, seg_part, data): self._ensureLoaded() try: return self.renderer.render(seg_part.content, data) except pystache.common.TemplateNotFoundError as ex: raise TemplateNotFoundError() from ex except pystache.common.PystacheError as ex: raise TemplatingError(str(ex), path) from ex def renderFile(self, paths, data): self._ensureLoaded() tpl = None logger.debug("Looking for template: %s" % paths) for p in paths: if not p.endswith('.mustache'): raise TemplatingError( "The Mustache template engine only accepts template " "filenames with a `.mustache` extension. Got: %s" % p) name = p[:-9] # strip `.mustache` try: tpl = self.renderer.load_template(name) except Exception as ex: logger.debug("Mustache error: %s" % ex) pass if tpl is None: raise TemplateNotFoundError() try: return self.renderer.render(tpl, data) except pystache.common.PystacheError as ex: raise TemplatingError(str(ex)) from ex def _ensureLoaded(self): if self.renderer: return self.renderer = _WorkaroundRenderer( search_dirs=self.app.templates_dirs) _knowns = ['PieCrustData', 'LazyPageConfigData', 'Paginator', 'Assetor', 'PageLinkerData'] class _WorkaroundRenderer(pystache.Renderer): def _make_resolve_context(self): mrc = super(_WorkaroundRenderer, self)._make_resolve_context() def _workaround(stack, name): # Pystache will treat anything that's not a string or a dict as # a list. This is just plain wrong, but it will take a while before # the project can get patches on Pypi. res = mrc(stack, name) if res is not None and ( res.__class__.__name__ in _knowns or isinstance(res, collections.abc.Mapping)): res = [res] return res return _workaround