# HG changeset patch # User Goffi # Date 1537297174 -7200 # Node ID da8f3ac86845a89219295ceeea5eb9e4aa9e036b # Parent 39d187f3698d9d5e2b2e3ca9a4e019f7927635ca template: overriden get_template to always have full template name: Environment.get_template has been overriden to have always full template name (i.e. template with (site/theme) prefix or absolute template). This is needed to correctly handle cache, so "base/base.html" is converted to "(some_site/some_theme)base/base.html" and won't conflict with an other theme "base/base.html". diff -r 39d187f3698d -r da8f3ac86845 sat/tools/common/template.py --- a/sat/tools/common/template.py Tue Sep 18 20:55:58 2018 +0200 +++ b/sat/tools/common/template.py Tue Sep 18 20:59:34 2018 +0200 @@ -313,6 +313,23 @@ return safe(u"\n".join(scripts)) +class Environment(jinja2.Environment): + + def get_template(self, name, parent=None, globals=None): + if name[0] not in (u'/', u'('): + # if name is not an absolute path or a full template name (this happen on + # extend or import during rendering), we convert it to a full template name. + # This is needed to handle cache correctly when a base template is overriden. + # Without that, we could not distinguish something like base/base.html if + # it's launched from some_site/some_theme or from [default]/default + name = u"({site}/{theme}){template}".format( + site=self._template_data.site, + theme=self._template_data.theme, + template=name) + + return super(Environment, self).get_template(name, parent, globals) + + class Renderer(object): def __init__(self, host, front_url_filter=None, trusted=False, private=False): @@ -355,13 +372,14 @@ normalised[name] = path self.sites_paths.update(normalised) - self.env = jinja2.Environment( + self.env = Environment( loader=TemplateLoader(sites_paths=self.sites_paths, trusted=trusted), autoescape=jinja2.select_autoescape(["html", "xhtml", "xml"]), trim_blocks=True, lstrip_blocks=True, extensions=["jinja2.ext.i18n"], ) + self.env._template_data = None self._locale_str = C.DEFAULT_LOCALE self._locale = Locale.parse(self._locale_str) self.installTranslations() @@ -831,6 +849,13 @@ else: template_data = self.env.loader.parse_template(template) + # we need to save template_data in environment, to load right templates when they + # are referenced from other templates (e.g. import) + # FIXME: this trick will not work anymore if we use async templates (it works + # here because we know that the rendering will be blocking until we unset + # _template_data) + self.env._template_data = template_data + template_source = self.env.get_template(template) if css_files is None: @@ -853,9 +878,10 @@ scripts_handler = ScriptsHandler(self, template_data) self.setLocale(locale) + # XXX: theme used in template arguments is the requested theme, which may differ # from actual theme if the template doesn't exist in the requested theme. - return template_source.render( + rendered = template_source.render( template_data=template_data, media_path=media_path, css_files=css_files, @@ -865,3 +891,5 @@ script=scripts_handler, **kwargs ) + self.env._template_data = None + return rendered