comparison sat/tools/common/template.py @ 2676:da8f3ac86845

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".
author Goffi <goffi@goffi.org>
date Tue, 18 Sep 2018 20:59:34 +0200
parents 39d187f3698d
children ae5340b57ff8
comparison
equal deleted inserted replaced
2675:39d187f3698d 2676:da8f3ac86845
311 path = self.renderer.getFrontURL(library_path) 311 path = self.renderer.getFrontURL(library_path)
312 scripts.append(tpl.format(src=quoteattr(path), attribute=attribute)) 312 scripts.append(tpl.format(src=quoteattr(path), attribute=attribute))
313 return safe(u"\n".join(scripts)) 313 return safe(u"\n".join(scripts))
314 314
315 315
316 class Environment(jinja2.Environment):
317
318 def get_template(self, name, parent=None, globals=None):
319 if name[0] not in (u'/', u'('):
320 # if name is not an absolute path or a full template name (this happen on
321 # extend or import during rendering), we convert it to a full template name.
322 # This is needed to handle cache correctly when a base template is overriden.
323 # Without that, we could not distinguish something like base/base.html if
324 # it's launched from some_site/some_theme or from [default]/default
325 name = u"({site}/{theme}){template}".format(
326 site=self._template_data.site,
327 theme=self._template_data.theme,
328 template=name)
329
330 return super(Environment, self).get_template(name, parent, globals)
331
332
316 class Renderer(object): 333 class Renderer(object):
317 334
318 def __init__(self, host, front_url_filter=None, trusted=False, private=False): 335 def __init__(self, host, front_url_filter=None, trusted=False, private=False):
319 """ 336 """
320 @param front_url_filter(callable): filter to retrieve real url of a directory/file 337 @param front_url_filter(callable): filter to retrieve real url of a directory/file
353 u"absolute path").format(name=name)) 370 u"absolute path").format(name=name))
354 continue 371 continue
355 normalised[name] = path 372 normalised[name] = path
356 self.sites_paths.update(normalised) 373 self.sites_paths.update(normalised)
357 374
358 self.env = jinja2.Environment( 375 self.env = Environment(
359 loader=TemplateLoader(sites_paths=self.sites_paths, trusted=trusted), 376 loader=TemplateLoader(sites_paths=self.sites_paths, trusted=trusted),
360 autoescape=jinja2.select_autoescape(["html", "xhtml", "xml"]), 377 autoescape=jinja2.select_autoescape(["html", "xhtml", "xml"]),
361 trim_blocks=True, 378 trim_blocks=True,
362 lstrip_blocks=True, 379 lstrip_blocks=True,
363 extensions=["jinja2.ext.i18n"], 380 extensions=["jinja2.ext.i18n"],
364 ) 381 )
382 self.env._template_data = None
365 self._locale_str = C.DEFAULT_LOCALE 383 self._locale_str = C.DEFAULT_LOCALE
366 self._locale = Locale.parse(self._locale_str) 384 self._locale = Locale.parse(self._locale_str)
367 self.installTranslations() 385 self.installTranslations()
368 # we want to have access to SàT constants in templates 386 # we want to have access to SàT constants in templates
369 self.env.globals[u"C"] = C 387 self.env.globals[u"C"] = C
829 template = u"({site}/{theme}){template}".format( 847 template = u"({site}/{theme}){template}".format(
830 site=site, theme=theme, template=template) 848 site=site, theme=theme, template=template)
831 else: 849 else:
832 template_data = self.env.loader.parse_template(template) 850 template_data = self.env.loader.parse_template(template)
833 851
852 # we need to save template_data in environment, to load right templates when they
853 # are referenced from other templates (e.g. import)
854 # FIXME: this trick will not work anymore if we use async templates (it works
855 # here because we know that the rendering will be blocking until we unset
856 # _template_data)
857 self.env._template_data = template_data
858
834 template_source = self.env.get_template(template) 859 template_source = self.env.get_template(template)
835 860
836 if css_files is None: 861 if css_files is None:
837 css_files, css_files_noscript = self.getCSSFiles(template_data) 862 css_files, css_files_noscript = self.getCSSFiles(template_data)
838 863
851 if css_contents: 876 if css_contents:
852 kwargs[u"css_content" + suffix] = u"\n".join(css_contents) 877 kwargs[u"css_content" + suffix] = u"\n".join(css_contents)
853 878
854 scripts_handler = ScriptsHandler(self, template_data) 879 scripts_handler = ScriptsHandler(self, template_data)
855 self.setLocale(locale) 880 self.setLocale(locale)
881
856 # XXX: theme used in template arguments is the requested theme, which may differ 882 # XXX: theme used in template arguments is the requested theme, which may differ
857 # from actual theme if the template doesn't exist in the requested theme. 883 # from actual theme if the template doesn't exist in the requested theme.
858 return template_source.render( 884 rendered = template_source.render(
859 template_data=template_data, 885 template_data=template_data,
860 media_path=media_path, 886 media_path=media_path,
861 css_files=css_files, 887 css_files=css_files,
862 css_files_noscript=css_files, 888 css_files_noscript=css_files,
863 locale=self._locale, 889 locale=self._locale,
864 gidx=Indexer(), 890 gidx=Indexer(),
865 script=scripts_handler, 891 script=scripts_handler,
866 **kwargs 892 **kwargs
867 ) 893 )
894 self.env._template_data = None
895 return rendered