comparison 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
comparison
equal deleted inserted replaced
1297:999dccf0093e 1298:8aba2a2078ca
1 """Integrate templating system using nunjucks"""
2
3 from js_modules.nunjucks import nunjucks
4 from browser import window, document
5 import javascript
6
7
8 safe = nunjucks.runtime.SafeString.new
9 env = nunjucks.configure(
10 window.templates_root_url,
11 {
12 'autoescape': True,
13 'trimBlocks': True,
14 'lstripBlocks': True,
15 })
16
17 nunjucks.installJinjaCompat()
18
19
20 class Indexer:
21 """Index global to a page"""
22
23 def __init__(self):
24 self._indexes = {}
25
26 def next(self, value):
27 if value not in self._indexes:
28 self._indexes[value] = 0
29 return 0
30 self._indexes[value] += 1
31 return self._indexes[value]
32
33 def current(self, value):
34 return self._indexes.get(value)
35
36
37 gidx = Indexer()
38 # suffix use to avoid collision with IDs generated in static page
39 SCRIPT_SUFF = "__script__"
40
41
42 def _next_gidx(value):
43 """Use next current global index as suffix"""
44 next_ = gidx.next(value)
45 return f"{value}{SCRIPT_SUFF}" if next_ == 0 else f"{value}_{SCRIPT_SUFF}{next_}"
46
47 env.addFilter("next_gidx", _next_gidx)
48
49
50 def _cur_gidx(value):
51 """Use current current global index as suffix"""
52 current = gidx.current(value)
53 return f"{value}{SCRIPT_SUFF}" if not current else f"{value}_{SCRIPT_SUFF}{current}"
54
55 env.addFilter("cur_gidx", _cur_gidx)
56
57
58 def _tojson(value):
59 return safe(
60 window.JSON.stringify(value)
61 .replace('&', '&amp;')
62 .replace('<', '&lt;')
63 .replace('>', '&gt;')
64 .replace('"', '&quot;')
65 )
66
67 env.addFilter("tojson", _tojson)
68
69
70 def _icon_use(name, cls=""):
71 kwargs = cls.to_dict()
72 cls = kwargs.get('cls')
73 return safe(
74 '<svg class="svg-icon{cls}" xmlns="http://www.w3.org/2000/svg" '
75 'viewBox="0 0 100 100">\n'
76 ' <use href="#{name}"/>'
77 '</svg>\n'.format(name=name, cls=(" " + cls) if cls else "")
78 )
79
80 env.addGlobal("icon", _icon_use)
81
82
83 class Template:
84
85 def __init__(self, tpl_name):
86 self._tpl = env.getTemplate(tpl_name, True)
87
88 def render(self, context):
89 return self._tpl.render(context)
90
91 def get_elt(self, context):
92 raw_html = self.render(context)
93 template_elt = document.createElement('template')
94 template_elt.innerHTML = raw_html
95 return template_elt.content.firstChild