Mercurial > libervia-web
diff libervia/pages/_browser/template.py @ 1298:8aba2a2078ca
browser: new template module:
this module integrate integrate to render templates from the browser.
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 19 Jun 2020 16:47:51 +0200 |
parents | |
children | c07112ef01cd |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libervia/pages/_browser/template.py Fri Jun 19 16:47:51 2020 +0200 @@ -0,0 +1,95 @@ +"""Integrate templating system using nunjucks""" + +from js_modules.nunjucks import nunjucks +from browser import window, document +import javascript + + +safe = nunjucks.runtime.SafeString.new +env = nunjucks.configure( + window.templates_root_url, + { + 'autoescape': True, + 'trimBlocks': True, + 'lstripBlocks': True, + }) + +nunjucks.installJinjaCompat() + + +class Indexer: + """Index global to a page""" + + def __init__(self): + self._indexes = {} + + def next(self, value): + if value not in self._indexes: + self._indexes[value] = 0 + return 0 + self._indexes[value] += 1 + return self._indexes[value] + + def current(self, value): + return self._indexes.get(value) + + +gidx = Indexer() +# suffix use to avoid collision with IDs generated in static page +SCRIPT_SUFF = "__script__" + + +def _next_gidx(value): + """Use next current global index as suffix""" + next_ = gidx.next(value) + return f"{value}{SCRIPT_SUFF}" if next_ == 0 else f"{value}_{SCRIPT_SUFF}{next_}" + +env.addFilter("next_gidx", _next_gidx) + + +def _cur_gidx(value): + """Use current current global index as suffix""" + current = gidx.current(value) + return f"{value}{SCRIPT_SUFF}" if not current else f"{value}_{SCRIPT_SUFF}{current}" + +env.addFilter("cur_gidx", _cur_gidx) + + +def _tojson(value): + return safe( + window.JSON.stringify(value) + .replace('&', '&') + .replace('<', '<') + .replace('>', '>') + .replace('"', '"') + ) + +env.addFilter("tojson", _tojson) + + +def _icon_use(name, cls=""): + kwargs = cls.to_dict() + cls = kwargs.get('cls') + return safe( + '<svg class="svg-icon{cls}" xmlns="http://www.w3.org/2000/svg" ' + 'viewBox="0 0 100 100">\n' + ' <use href="#{name}"/>' + '</svg>\n'.format(name=name, cls=(" " + cls) if cls else "") + ) + +env.addGlobal("icon", _icon_use) + + +class Template: + + def __init__(self, tpl_name): + self._tpl = env.getTemplate(tpl_name, True) + + def render(self, context): + return self._tpl.render(context) + + def get_elt(self, context): + raw_html = self.render(context) + template_elt = document.createElement('template') + template_elt.innerHTML = raw_html + return template_elt.content.firstChild