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