annotate src/tools/common/template.py @ 2452:7aa863cbc47f

template: remove extension from elements while looking for a path: this way, extension doesn't need to be provided for a CSS file for a single page.
author Goffi <goffi@goffi.org>
date Thu, 30 Nov 2017 20:58:34 +0100
parents d294527bd46f
children 84e84a46b014
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/env python2
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2 # -*- coding: utf-8 -*-
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
3
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
4 # SAT: a jabber client
2414
8b37a62336c3 misc: date update (yes it's a bit late :p )
Goffi <goffi@goffi.org>
parents: 2403
diff changeset
5 # Copyright (C) 2009-2017 Jérôme Poisson (goffi@goffi.org)
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
6
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # This program is free software: you can redistribute it and/or modify
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # it under the terms of the GNU Affero General Public License as published by
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # the Free Software Foundation, either version 3 of the License, or
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
10 # (at your option) any later version.
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
11
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # This program is distributed in the hope that it will be useful,
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
15 # GNU Affero General Public License for more details.
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
16
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # You should have received a copy of the GNU Affero General Public License
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
19
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
20 """ template generation """
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
21
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
22 from sat.core.constants import Const as C
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
23 from sat.core.i18n import _
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
24 from sat.core import exceptions
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
25 from sat.core.log import getLogger
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
26 log = getLogger(__name__)
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
27 import os.path
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
28 from xml.sax.saxutils import quoteattr
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
29 import time
2401
221478058d8a template: improved attribute escaping, and added it to filters under the name "attr_escape"
Goffi <goffi@goffi.org>
parents: 2394
diff changeset
30 import re
2249
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
31 from babel import support
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
32 from babel import Locale
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
33 from babel.core import UnknownLocaleError
2403
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
34 from babel import dates
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
35 try:
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
36 import sat_templates
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
37 except ImportError:
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
38 raise exceptions.MissingModule(u'sat_templates module is not available, please install it or check your path to use template engine')
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
39 else:
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
40 sat_templates # to avoid pyflakes warning
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
41
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
42 try:
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
43 import jinja2
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
44 except:
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
45 raise exceptions.MissingModule(u'Missing module jinja2, please install it from http://jinja.pocoo.org or with pip install jinja2')
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
46
2265
322694543225 tools (common/template): ScriptsHandler fix/improvments:
Goffi <goffi@goffi.org>
parents: 2249
diff changeset
47 from jinja2 import Markup as safe
2403
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
48 from jinja2 import is_undefined
2265
322694543225 tools (common/template): ScriptsHandler fix/improvments:
Goffi <goffi@goffi.org>
parents: 2249
diff changeset
49
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
50 HTML_EXT = ('html', 'xhtml')
2403
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
51 DEFAULT_LOCALE = u'en_GB'
2401
221478058d8a template: improved attribute escaping, and added it to filters under the name "attr_escape"
Goffi <goffi@goffi.org>
parents: 2394
diff changeset
52 RE_ATTR_ESCAPE = re.compile(r'[^a-z_-]')
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
53 # TODO: handle external path (an additional search path for templates should be settable by user
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
54 # TODO: handle absolute URL (should be used for trusted use cases) only (e.g. jp) for security reason
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
55
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
56
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
57 class TemplateLoader(jinja2.FileSystemLoader):
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
58
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
59 def __init__(self):
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
60 searchpath = os.path.dirname(sat_templates.__file__)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
61 super(TemplateLoader, self).__init__(searchpath, followlinks=True)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
62
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
63 def parse_template(self, template):
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
64 """parse template path and return theme and relative URL
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
65
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
66 @param template_path(unicode): path to template with parenthesis syntax
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
67 @return (tuple[(unicode,None),unicode]): theme and template_path
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
68 theme can be None if relative path is used
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
69 relative path is the path from search path with theme specified
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
70 e.g. default/blog/articles.html
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
71 """
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
72 if template.startswith(u'('):
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
73 try:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
74 theme_end = template.index(u')')
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
75 except IndexError:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
76 raise ValueError(u"incorrect theme in template")
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
77 theme = template[1:theme_end]
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
78 template = template[theme_end+1:]
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
79 if not template or template.startswith(u'/'):
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
80 raise ValueError(u"incorrect path after template name")
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
81 template = os.path.join(theme, template)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
82 elif template.startswith(u'/'):
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
83 # absolute path means no template
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
84 theme = None
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
85 raise NotImplementedError(u'absolute path is not implemented yet')
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
86 else:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
87 theme = C.TEMPLATE_THEME_DEFAULT
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
88 template = os.path.join(theme, template)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
89 return theme, template
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
90
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
91 def get_default_template(self, theme, template_path):
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
92 """return default template path
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
93
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
94 @param theme(unicode): theme used
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
95 @param template_path(unicode): path to the not found template
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
96 @return (unicode, None): default path or None if there is not
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
97 """
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
98 ext = os.path.splitext(template_path)[1][1:]
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
99 path_elems = template_path.split(u'/')
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
100 if ext in HTML_EXT:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
101 if path_elems[1] == u'error':
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
102 # if an inexisting error page is requested, we return base page
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
103 default_path = os.path.join(theme, u'error/base.html')
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
104 return default_path
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
105 if theme != C.TEMPLATE_THEME_DEFAULT:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
106 # if template doesn't exists for this theme, we try with default
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
107 return os.path.join(C.TEMPLATE_THEME_DEFAULT, path_elems[1:])
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
108
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
109 def get_source(self, environment, template):
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
110 """relative path to template dir, with special theme handling
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
111
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
112 if the path is just relative, "default" theme is used.
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
113 The theme can be specified in parenthesis just before the path
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
114 e.g.: (some_theme)path/to/template.html
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
115 """
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
116 theme, template_path = self.parse_template(template)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
117 try:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
118 return super(TemplateLoader, self).get_source(environment, template_path)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
119 except jinja2.exceptions.TemplateNotFound as e:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
120 # in some special cases, a defaut template is returned if nothing is found
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
121 if theme is not None:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
122 default_path = self.get_default_template(theme, template_path)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
123 if default_path is not None:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
124 return super(TemplateLoader, self).get_source(environment, default_path)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
125 # if no default template is found, we re-raise the error
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
126 raise e
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
127
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
128
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
129 class Indexer(object):
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
130 """Index global to a page"""
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
131
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
132 def __init__(self):
2385
39d30cf722cb template: gidx methods improvment:
Goffi <goffi@goffi.org>
parents: 2384
diff changeset
133 self._indexes = {}
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
134
2385
39d30cf722cb template: gidx methods improvment:
Goffi <goffi@goffi.org>
parents: 2384
diff changeset
135 def next(self, value):
39d30cf722cb template: gidx methods improvment:
Goffi <goffi@goffi.org>
parents: 2384
diff changeset
136 if value not in self._indexes:
39d30cf722cb template: gidx methods improvment:
Goffi <goffi@goffi.org>
parents: 2384
diff changeset
137 self._indexes[value] = 0
39d30cf722cb template: gidx methods improvment:
Goffi <goffi@goffi.org>
parents: 2384
diff changeset
138 return 0
39d30cf722cb template: gidx methods improvment:
Goffi <goffi@goffi.org>
parents: 2384
diff changeset
139 self._indexes[value] += 1
39d30cf722cb template: gidx methods improvment:
Goffi <goffi@goffi.org>
parents: 2384
diff changeset
140 return self._indexes[value]
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
141
2385
39d30cf722cb template: gidx methods improvment:
Goffi <goffi@goffi.org>
parents: 2384
diff changeset
142 def current(self, value):
39d30cf722cb template: gidx methods improvment:
Goffi <goffi@goffi.org>
parents: 2384
diff changeset
143 return self._indexes.get(value)
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
144
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
145
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
146 class ScriptsHandler(object):
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
147
2265
322694543225 tools (common/template): ScriptsHandler fix/improvments:
Goffi <goffi@goffi.org>
parents: 2249
diff changeset
148 def __init__(self, renderer, template_path, template_root_dir, root_path):
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
149 self.renderer = renderer
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
150 self.template_root_dir = template_root_dir
2265
322694543225 tools (common/template): ScriptsHandler fix/improvments:
Goffi <goffi@goffi.org>
parents: 2249
diff changeset
151 self.root_path = root_path
322694543225 tools (common/template): ScriptsHandler fix/improvments:
Goffi <goffi@goffi.org>
parents: 2249
diff changeset
152 self.scripts = [] # we don't use a set because order may be important
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
153 dummy, self.theme, self.is_default_theme = renderer.getThemeData(template_path)
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
154
2265
322694543225 tools (common/template): ScriptsHandler fix/improvments:
Goffi <goffi@goffi.org>
parents: 2249
diff changeset
155 def include(self, library_name):
322694543225 tools (common/template): ScriptsHandler fix/improvments:
Goffi <goffi@goffi.org>
parents: 2249
diff changeset
156 """Mark that a script need to be imported.
322694543225 tools (common/template): ScriptsHandler fix/improvments:
Goffi <goffi@goffi.org>
parents: 2249
diff changeset
157
322694543225 tools (common/template): ScriptsHandler fix/improvments:
Goffi <goffi@goffi.org>
parents: 2249
diff changeset
158 Must be used before base.html is extended, as <script> are generated there.
322694543225 tools (common/template): ScriptsHandler fix/improvments:
Goffi <goffi@goffi.org>
parents: 2249
diff changeset
159 If called several time with the same library, it will be imported once.
322694543225 tools (common/template): ScriptsHandler fix/improvments:
Goffi <goffi@goffi.org>
parents: 2249
diff changeset
160 @param library_name(unicode): name of the library to import
322694543225 tools (common/template): ScriptsHandler fix/improvments:
Goffi <goffi@goffi.org>
parents: 2249
diff changeset
161 """
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
162 if library_name.endswith('.js'):
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
163 library_name = library_name[:-3]
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
164 if library_name not in self.scripts:
2265
322694543225 tools (common/template): ScriptsHandler fix/improvments:
Goffi <goffi@goffi.org>
parents: 2249
diff changeset
165 self.scripts.append(library_name)
322694543225 tools (common/template): ScriptsHandler fix/improvments:
Goffi <goffi@goffi.org>
parents: 2249
diff changeset
166 return u''
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
167
2265
322694543225 tools (common/template): ScriptsHandler fix/improvments:
Goffi <goffi@goffi.org>
parents: 2249
diff changeset
168 def generate_scripts(self):
322694543225 tools (common/template): ScriptsHandler fix/improvments:
Goffi <goffi@goffi.org>
parents: 2249
diff changeset
169 """Generate the <script> elements
322694543225 tools (common/template): ScriptsHandler fix/improvments:
Goffi <goffi@goffi.org>
parents: 2249
diff changeset
170
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
171 @return (unicode): <scripts> HTML tags
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
172 """
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
173 scripts = []
2265
322694543225 tools (common/template): ScriptsHandler fix/improvments:
Goffi <goffi@goffi.org>
parents: 2249
diff changeset
174 tpl = u'<script src={src}></script>'
322694543225 tools (common/template): ScriptsHandler fix/improvments:
Goffi <goffi@goffi.org>
parents: 2249
diff changeset
175 for library in self.scripts:
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
176 path = self.renderer.getStaticPath(library, self.template_root_dir, self.theme, self.is_default_theme, '.js')
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
177 if path is None:
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
178 log.warning(_(u"Can't find {}.js javascript library").format(library))
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
179 continue
2265
322694543225 tools (common/template): ScriptsHandler fix/improvments:
Goffi <goffi@goffi.org>
parents: 2249
diff changeset
180 path = os.path.join(self.root_path, path)
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
181 scripts.append(tpl.format(src=quoteattr(path)))
2265
322694543225 tools (common/template): ScriptsHandler fix/improvments:
Goffi <goffi@goffi.org>
parents: 2249
diff changeset
182 return safe(u'\n'.join(scripts))
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
183
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
184
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
185 class Renderer(object):
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
186
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
187 def __init__(self, host):
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
188 self.host = host
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
189 self.base_dir = os.path.dirname(sat_templates.__file__) # FIXME: should be modified if we handle use extra dirs
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
190 self.env = jinja2.Environment(
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
191 loader=TemplateLoader(),
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
192 autoescape=jinja2.select_autoescape(['html', 'xhtml', 'xml']),
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
193 trim_blocks=True,
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
194 lstrip_blocks=True,
2249
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
195 extensions=['jinja2.ext.i18n'],
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
196 )
2249
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
197 self._locale_str = DEFAULT_LOCALE
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
198 self._locale = Locale.parse(self._locale_str)
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
199 self.installTranslations()
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
200 # we want to have access to SàT constants in templates
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
201 self.env.globals[u'C'] = C
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
202 # custom filters
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
203 self.env.filters['next_gidx'] = self._next_gidx
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
204 self.env.filters['cur_gidx'] = self._cur_gidx
2403
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
205 self.env.filters['date_fmt'] = self._date_fmt
2384
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
206 self.env.filters['xmlui_class'] = self._xmlui_class
2401
221478058d8a template: improved attribute escaping, and added it to filters under the name "attr_escape"
Goffi <goffi@goffi.org>
parents: 2394
diff changeset
207 self.env.filters['attr_escape'] = self.attr_escape
2402
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
208 self.env.filters['item_filter'] = self._item_filter
2391
07e1543d6992 template: new "adv_format" filter which use Python's format and return whole value if template is None
Goffi <goffi@goffi.org>
parents: 2385
diff changeset
209 self.env.filters['adv_format'] = self._adv_format
2425
d294527bd46f template: added dict_ext filter to extend a dictionary
Goffi <goffi@goffi.org>
parents: 2422
diff changeset
210 self.env.filters['dict_ext'] = self._dict_ext
2403
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
211 # custom tests
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
212 self.env.tests['in_the_past'] = self._in_the_past
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
213
2249
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
214 def installTranslations(self):
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
215 i18n_dir = os.path.join(self.base_dir, 'i18n')
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
216 self.translations = {}
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
217 for lang_dir in os.listdir(i18n_dir):
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
218 lang_path = os.path.join(i18n_dir, lang_dir)
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
219 if not os.path.isdir(lang_path):
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
220 continue
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
221 po_path = os.path.join(lang_path, 'LC_MESSAGES/sat.mo')
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
222 try:
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
223 with open(po_path, 'rb') as f:
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
224 self.translations[Locale.parse(lang_dir)] = support.Translations(f, 'sat')
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
225 except EnvironmentError:
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
226 log.error(_(u"Can't find template translation at {path}").format(path = po_path))
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
227 except UnknownLocaleError as e:
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
228 log.error(_(u"Invalid locale name: {msg}").format(msg=e))
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
229 else:
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
230 log.info(_(u'loaded {lang} templates translations').format(lang=lang_dir))
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
231 self.env.install_null_translations(True)
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
232
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
233 def setLocale(self, locale_str):
2403
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
234 """set current locale
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
235
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
236 change current translation locale and self self._locale and self._locale_str
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
237 """
2249
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
238 if locale_str == self._locale_str:
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
239 return
2403
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
240 if locale_str == 'en':
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
241 # we default to GB English when it's not specified
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
242 # one of the main reason is to avoid the nonsense U.S. short date format
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
243 locale_str = 'en_GB'
2323
2dae79990122 template: print warning message and use DEFAULT_LOCALE on bad locale
Goffi <goffi@goffi.org>
parents: 2266
diff changeset
244 try:
2dae79990122 template: print warning message and use DEFAULT_LOCALE on bad locale
Goffi <goffi@goffi.org>
parents: 2266
diff changeset
245 locale = Locale.parse(locale_str)
2dae79990122 template: print warning message and use DEFAULT_LOCALE on bad locale
Goffi <goffi@goffi.org>
parents: 2266
diff changeset
246 except ValueError as e:
2dae79990122 template: print warning message and use DEFAULT_LOCALE on bad locale
Goffi <goffi@goffi.org>
parents: 2266
diff changeset
247 log.warning(_(u"invalid locale value: {msg}").format(msg=e))
2dae79990122 template: print warning message and use DEFAULT_LOCALE on bad locale
Goffi <goffi@goffi.org>
parents: 2266
diff changeset
248 locale_str = self._locale_str = DEFAULT_LOCALE
2dae79990122 template: print warning message and use DEFAULT_LOCALE on bad locale
Goffi <goffi@goffi.org>
parents: 2266
diff changeset
249 locale = Locale.parse(locale_str)
2dae79990122 template: print warning message and use DEFAULT_LOCALE on bad locale
Goffi <goffi@goffi.org>
parents: 2266
diff changeset
250
2249
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
251 locale_str = unicode(locale)
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
252 if locale_str != DEFAULT_LOCALE:
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
253 try:
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
254 translations = self.translations[locale]
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
255 except KeyError:
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
256 log.warning(_(u"Can't find locale {locale}".format(locale=locale)))
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
257 locale_str = DEFAULT_LOCALE
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
258 locale = Locale.parse(self._locale_str)
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
259 else:
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
260 self.env.install_gettext_translations(translations, True)
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
261 log.debug(_(u'Switched to {lang}').format(lang=locale.english_name))
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
262
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
263 if locale_str == DEFAULT_LOCALE:
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
264 self.env.install_null_translations(True)
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
265
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
266 self._locale = locale
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
267 self._locale_str = locale_str
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
268
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
269 def getThemeAndRoot(self, template):
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
270 """retrieve theme and root dir of a given tempalte
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
271
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
272 @param template(unicode): template to parse
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
273 @return (tuple[unicode, unicode]): theme and absolute path to theme's root dir
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
274 """
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
275 theme, dummy = self.env.loader.parse_template(template)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
276 return theme, os.path.join(self.base_dir, theme)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
277
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
278 def getStaticPath(self, name, template_root_dir, theme, is_default, ext='.css'):
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
279 """retrieve path of a static file if it exists with current theme or default
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
280
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
281 File will be looked at [theme]/static/[name][ext], and then default
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
282 if not found.
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
283 @param name(unicode): name of the file to look for
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
284 @param template_root_dir(unicode): absolute path to template root used
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
285 @param theme(unicode): name of the template theme used
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
286 @param is_default(bool): True if theme is the default theme
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
287 @return (unicode, None): relative path if found, else None
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
288 """
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
289 file_ = None
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
290 path = os.path.join(theme, C.TEMPLATE_STATIC_DIR, name + ext)
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
291 if os.path.exists(os.path.join(template_root_dir, path)):
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
292 file_ = path
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
293 elif not is_default:
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
294 path = os.path.join(C.TEMPLATE_THEME_DEFAULT, C.TEMPLATE_STATIC_DIR, name + ext)
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
295 if os.path.exists(os.path.join(template_root_dir, path)):
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
296 file_.append(path)
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
297 return file_
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
298
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
299 def getThemeData(self, template_path):
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
300 """return template data got from template_path
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
301
2452
7aa863cbc47f template: remove extension from elements while looking for a path:
Goffi <goffi@goffi.org>
parents: 2425
diff changeset
302 @return tuple(unicode, unicode, bool):
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
303 path_elems: elements of the path
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
304 theme: theme of the page
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
305 is_default: True if the theme is the default theme
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
306 """
2452
7aa863cbc47f template: remove extension from elements while looking for a path:
Goffi <goffi@goffi.org>
parents: 2425
diff changeset
307 path_elems = [os.path.splitext(p)[0] for p in template_path.split(u'/')]
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
308 theme = path_elems.pop(0)
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
309 is_default = theme == C.TEMPLATE_THEME_DEFAULT
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
310 return (path_elems, theme, is_default)
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
311
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
312 def getCSSFiles(self, template_path, template_root_dir):
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
313 """retrieve CSS files to use according to theme and template path
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
314
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
315 for each element of the path, a .css file is looked for in /static, and returned if it exists.
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
316 previous element are kept by replacing '/' with '_', and styles.css is always returned.
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
317 For instance, if template_path is some_theme/blog/articles.html:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
318 some_theme/static/styles.css is returned if it exists else default/static/styles.css
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
319 some_theme/static/blog.css is returned if it exists else default/static/blog.css (if it exists too)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
320 some_theme/static/blog_articles.css is returned if it exists else default/static/blog_articles.css (if it exists too)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
321 @param template_path(unicode): relative path to template file (e.g. some_theme/blog/articles.html)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
322 @param template_root_dir(unicode): absolute path of the theme root dir used
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
323 @return list[unicode]: relative path to CSS files to use
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
324 """
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
325 # TODO: some caching would be nice
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
326 css_files = []
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
327 path_elems, theme, is_default = self.getThemeData(template_path)
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
328 for css in (u'fonts', u'styles'):
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
329 css_path = self.getStaticPath(css, template_root_dir, theme, is_default)
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
330 if css_path is not None:
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
331 css_files.append(css_path)
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
332
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
333 for idx, path in enumerate(path_elems):
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
334 css_path = self.getStaticPath(u'_'.join(path_elems[:idx+1]), template_root_dir, theme, is_default)
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
335 if css_path is not None:
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
336 css_files.append(css_path)
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
337
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
338 return css_files
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
339
2403
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
340
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
341 ## custom filters ##
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
342
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
343 @jinja2.contextfilter
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
344 def _next_gidx(self, ctx, value):
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
345 """Use next current global index as suffix"""
2385
39d30cf722cb template: gidx methods improvment:
Goffi <goffi@goffi.org>
parents: 2384
diff changeset
346 next_ = ctx['gidx'].next(value)
39d30cf722cb template: gidx methods improvment:
Goffi <goffi@goffi.org>
parents: 2384
diff changeset
347 return value if next_ == 0 else u"{}_{}".format(value, next_)
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
348
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
349 @jinja2.contextfilter
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
350 def _cur_gidx(self, ctx, value):
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
351 """Use current current global index as suffix"""
2385
39d30cf722cb template: gidx methods improvment:
Goffi <goffi@goffi.org>
parents: 2384
diff changeset
352 current = ctx['gidx'].current(value)
39d30cf722cb template: gidx methods improvment:
Goffi <goffi@goffi.org>
parents: 2384
diff changeset
353 return value if not current else u"{}_{}".format(value, current)
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
354
2403
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
355 def _date_fmt(self, timestamp, fmt='short', date_only=False, auto_limit=None, auto_old_fmt=None):
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
356 """format date according to locale
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
357
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
358 @param timestamp(basestring, int): unix time
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
359 @param fmt(str): one of:
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
360 - short: e.g. u'31/12/17'
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
361 - medium: e.g. u'Apr 1, 2007'
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
362 - long: e.g. u'April 1, 2007'
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
363 - full: e.g. u'Sunday, April 1, 2007'
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
364 - relative: format in relative time
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
365 e.g.: 3 hours
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
366 note that this format is not precise
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
367 - iso: ISO 8601 format
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
368 e.g.: u'2007-04-01T19:53:23Z'
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
369 - auto_limit (int, None): limit in days before using auto_old_fmt
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
370 None: use default(7 days)
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
371 - auto_old_fmt(unicode, None): format to use when date is olded than limit
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
372 None: use default(short)
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
373 or a free value which is passed to babel.dates.format_datetime
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
374 @param date_only(bool): if True, only display date (not datetime)
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
375
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
376 """
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
377 if is_undefined(fmt):
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
378 fmt = u'short'
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
379
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
380 if (auto_limit is not None or auto_old_fmt is not None) and fmt != 'auto':
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
381 raise ValueError(u'auto argument can only be used with auto fmt')
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
382 if fmt == 'auto':
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
383 days_delta = (time.time() - int(timestamp)) / 3600
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
384 if days_delta > (auto_limit or 7):
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
385 fmt = auto_old_fmt or 'short'
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
386 else:
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
387 fmt = 'relative'
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
388
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
389 if fmt == 'relative':
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
390 delta = int(timestamp) - time.time()
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
391 return dates.format_timedelta(delta, granularity="minute", add_direction=True, locale=self._locale_str)
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
392 elif fmt in ('short', 'long'):
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
393 formatter = dates.format_date if date_only else dates.format_datetime
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
394 return formatter(int(timestamp), format=fmt, locale=self._locale_str)
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
395 elif fmt == 'iso':
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
396 if date_only:
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
397 fmt = 'yyyy-MM-dd'
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
398 else:
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
399 fmt = "yyyy-MM-ddTHH:mm:ss'Z'"
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
400 return dates.format_datetime(int(timestamp), format=fmt)
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
401 else:
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
402 return dates.format_datetime(int(timestamp), format=fmt, locale=self._locale_str)
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
403
2384
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
404 def attr_escape(self, text):
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
405 """escape a text to a value usable as an attribute
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
406
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
407 remove spaces, and put in lower case
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
408 """
2401
221478058d8a template: improved attribute escaping, and added it to filters under the name "attr_escape"
Goffi <goffi@goffi.org>
parents: 2394
diff changeset
409 return RE_ATTR_ESCAPE.sub(u'_', text.strip().lower())[:50]
2384
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
410
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
411 def _xmlui_class(self, xmlui_item, fields):
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
412 """return classes computed from XMLUI fields name
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
413
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
414 will return a string with a series of escaped {name}_{value} separated by spaces.
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
415 @param xmlui_item(xmlui.XMLUIPanel): XMLUI containing the widgets to use
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
416 @param fields(iterable(unicode)): names of the widgets to use
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
417 @return (unicode, None): computer string to use as class attribute value
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
418 None if no field was specified
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
419 """
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
420 classes = []
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
421 for name in fields:
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
422 escaped_name = self.attr_escape(name)
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
423 try:
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
424 for value in xmlui_item.widgets[name].values:
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
425 classes.append(escaped_name + '_' + self.attr_escape(value))
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
426 except KeyError:
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
427 log.debug(_(u"ignoring field \"{name}\": it doesn't exists").format(name=name))
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
428 continue
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
429 return u' '.join(classes) or None
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
430
2422
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
431 @jinja2.contextfilter
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
432 def _item_filter(self, ctx, item, filters):
2402
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
433 """return item's value, filtered if suitable
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
434
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
435 @param item(object): item to filter
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
436 value must have name and value attributes,
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
437 mostly used for XMLUI items
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
438 @param filters(dict[unicode, (callable, dict, None)]): map of name => filter
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
439 if filter is None, return the value unchanged
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
440 if filter is a callable, apply it
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
441 if filter is a dict, it can have following keys:
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
442 - filters: iterable of filters to apply
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
443 - filters_args: kwargs of filters in the same order as filters (use empty dict if needed)
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
444 - template: template to format where {value} is the filtered value
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
445 """
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
446 value = item.value
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
447 filter_ = filters.get(item.name, None)
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
448 if filter_ is None:
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
449 return value
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
450 elif isinstance(filter_, dict):
2422
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
451 filters_args = filter_.get(u'filters_args')
2402
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
452 for idx, f_name in enumerate(filter_.get(u'filters', [])):
2422
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
453 kwargs = filters_args[idx] if filters_args is not None else {}
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
454 filter_func = self.env.filters[f_name]
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
455 try:
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
456 eval_context_filter = filter_func.evalcontextfilter
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
457 except AttributeError:
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
458 eval_context_filter = False
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
459
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
460 if eval_context_filter:
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
461 value = filter_func(ctx.eval_ctx, value, **kwargs)
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
462 else:
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
463 value = filter_func(value, **kwargs)
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
464 template = filter_.get(u'template')
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
465 if template:
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
466 # format will return a string, so we need to check first
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
467 # if the value is safe or not, and re-mark it after formatting
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
468 is_safe = isinstance(value, safe)
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
469 value = template.format(value=value)
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
470 if is_safe:
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
471 value = safe(value)
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
472 return value
2402
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
473
2391
07e1543d6992 template: new "adv_format" filter which use Python's format and return whole value if template is None
Goffi <goffi@goffi.org>
parents: 2385
diff changeset
474 def _adv_format(self, value, template, **kwargs):
07e1543d6992 template: new "adv_format" filter which use Python's format and return whole value if template is None
Goffi <goffi@goffi.org>
parents: 2385
diff changeset
475 """Advancer formatter
07e1543d6992 template: new "adv_format" filter which use Python's format and return whole value if template is None
Goffi <goffi@goffi.org>
parents: 2385
diff changeset
476
07e1543d6992 template: new "adv_format" filter which use Python's format and return whole value if template is None
Goffi <goffi@goffi.org>
parents: 2385
diff changeset
477 like format() method, but take care or special values like None
07e1543d6992 template: new "adv_format" filter which use Python's format and return whole value if template is None
Goffi <goffi@goffi.org>
parents: 2385
diff changeset
478 @param value(unicode): value to format
07e1543d6992 template: new "adv_format" filter which use Python's format and return whole value if template is None
Goffi <goffi@goffi.org>
parents: 2385
diff changeset
479 @param template(None, unicode): template to use with format() method.
07e1543d6992 template: new "adv_format" filter which use Python's format and return whole value if template is None
Goffi <goffi@goffi.org>
parents: 2385
diff changeset
480 It will be formatted using value=value and **kwargs
07e1543d6992 template: new "adv_format" filter which use Python's format and return whole value if template is None
Goffi <goffi@goffi.org>
parents: 2385
diff changeset
481 None to return value unchanged
07e1543d6992 template: new "adv_format" filter which use Python's format and return whole value if template is None
Goffi <goffi@goffi.org>
parents: 2385
diff changeset
482 @return (unicode): formatted value
07e1543d6992 template: new "adv_format" filter which use Python's format and return whole value if template is None
Goffi <goffi@goffi.org>
parents: 2385
diff changeset
483 """
07e1543d6992 template: new "adv_format" filter which use Python's format and return whole value if template is None
Goffi <goffi@goffi.org>
parents: 2385
diff changeset
484 if template is None:
07e1543d6992 template: new "adv_format" filter which use Python's format and return whole value if template is None
Goffi <goffi@goffi.org>
parents: 2385
diff changeset
485 return value
07e1543d6992 template: new "adv_format" filter which use Python's format and return whole value if template is None
Goffi <goffi@goffi.org>
parents: 2385
diff changeset
486 # jinja use string when no special char is used, so we have to convert to unicode
07e1543d6992 template: new "adv_format" filter which use Python's format and return whole value if template is None
Goffi <goffi@goffi.org>
parents: 2385
diff changeset
487 return unicode(template).format(value=value, **kwargs)
07e1543d6992 template: new "adv_format" filter which use Python's format and return whole value if template is None
Goffi <goffi@goffi.org>
parents: 2385
diff changeset
488
2425
d294527bd46f template: added dict_ext filter to extend a dictionary
Goffi <goffi@goffi.org>
parents: 2422
diff changeset
489 def _dict_ext(self, source_dict, extra_dict, key=None):
d294527bd46f template: added dict_ext filter to extend a dictionary
Goffi <goffi@goffi.org>
parents: 2422
diff changeset
490 """extend source_dict with extra dict and return the result
d294527bd46f template: added dict_ext filter to extend a dictionary
Goffi <goffi@goffi.org>
parents: 2422
diff changeset
491
d294527bd46f template: added dict_ext filter to extend a dictionary
Goffi <goffi@goffi.org>
parents: 2422
diff changeset
492 @param source_dict(dict): dictionary to extend
d294527bd46f template: added dict_ext filter to extend a dictionary
Goffi <goffi@goffi.org>
parents: 2422
diff changeset
493 @param extra_dict(dict, None): dictionary to use to extend first one
d294527bd46f template: added dict_ext filter to extend a dictionary
Goffi <goffi@goffi.org>
parents: 2422
diff changeset
494 None to return source_dict unmodified
d294527bd46f template: added dict_ext filter to extend a dictionary
Goffi <goffi@goffi.org>
parents: 2422
diff changeset
495 @param key(unicode, None): if specified extra_dict[key] will be used
d294527bd46f template: added dict_ext filter to extend a dictionary
Goffi <goffi@goffi.org>
parents: 2422
diff changeset
496 if it doesn't exists, a copy of unmodified source_dict is returned
d294527bd46f template: added dict_ext filter to extend a dictionary
Goffi <goffi@goffi.org>
parents: 2422
diff changeset
497 @return (dict): resulting dictionary
d294527bd46f template: added dict_ext filter to extend a dictionary
Goffi <goffi@goffi.org>
parents: 2422
diff changeset
498 """
d294527bd46f template: added dict_ext filter to extend a dictionary
Goffi <goffi@goffi.org>
parents: 2422
diff changeset
499 if extra_dict is None:
d294527bd46f template: added dict_ext filter to extend a dictionary
Goffi <goffi@goffi.org>
parents: 2422
diff changeset
500 return source_dict
d294527bd46f template: added dict_ext filter to extend a dictionary
Goffi <goffi@goffi.org>
parents: 2422
diff changeset
501 if key is not None:
d294527bd46f template: added dict_ext filter to extend a dictionary
Goffi <goffi@goffi.org>
parents: 2422
diff changeset
502 extra_dict = extra_dict.get(key, {})
d294527bd46f template: added dict_ext filter to extend a dictionary
Goffi <goffi@goffi.org>
parents: 2422
diff changeset
503 ret = source_dict.copy()
d294527bd46f template: added dict_ext filter to extend a dictionary
Goffi <goffi@goffi.org>
parents: 2422
diff changeset
504 ret.update(extra_dict)
d294527bd46f template: added dict_ext filter to extend a dictionary
Goffi <goffi@goffi.org>
parents: 2422
diff changeset
505 return ret
d294527bd46f template: added dict_ext filter to extend a dictionary
Goffi <goffi@goffi.org>
parents: 2422
diff changeset
506
2403
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
507 ## custom tests ##
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
508
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
509 def _in_the_past(self, timestamp):
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
510 """check if a date is in the past
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
511
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
512 @param timestamp(unicode, int): unix time
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
513 @return (bool): True if date is in the past
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
514 """
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
515 return time.time() > int(timestamp)
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
516
2394
7bfcc431f66d template: added media_path to template data
Goffi <goffi@goffi.org>
parents: 2391
diff changeset
517 def render(self, template, theme=None, locale=DEFAULT_LOCALE, root_path=u'', media_path=u'', css_files=None, css_inline=False, **kwargs):
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
518 """render a template
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
519
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
520 @param template(unicode): template to render (e.g. blog/articles.html)
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
521 @param theme(unicode): template theme
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
522 @param root_path(unicode): prefix of the path/URL to use for template root
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
523 must end with a u'/'
2394
7bfcc431f66d template: added media_path to template data
Goffi <goffi@goffi.org>
parents: 2391
diff changeset
524 @param media_path(unicode): prefix of the SàT media path/URL to use for template root
7bfcc431f66d template: added media_path to template data
Goffi <goffi@goffi.org>
parents: 2391
diff changeset
525 must end with a u'/'
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
526 @param css_files(list[unicode],None): CSS files to used
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
527 CSS files must be in static dir of the template
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
528 use None for automatic selection of CSS files based on template category
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
529 None is recommended. General static/style.css and theme file name will be used.
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
530 @param css_inline(bool): if True, CSS will be embedded in the HTML page
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
531 @param **kwargs: variable to transmit to the template
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
532 """
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
533 if not template:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
534 raise ValueError(u"template can't be empty")
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
535 if theme is not None:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
536 # use want to set a theme, we add it to the template path
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
537 if template[0] == u'(':
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
538 raise ValueError(u"you can't specify theme in template path and in argument at the same time")
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
539 elif template[0] == u'/':
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
540 raise ValueError(u"you can't specify theme with absolute paths")
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
541 template= u'(' + theme + u')' + template
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
542 else:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
543 theme, dummy = self.env.loader.parse_template(template)
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
544
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
545 template_source = self.env.get_template(template)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
546 template_root_dir = os.path.normpath(self.base_dir) # FIXME: should be modified if we handle use extra dirs
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
547 # XXX: template_path may have a different theme as first element than theme if a default page is used
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
548 template_path = template_source.filename[len(template_root_dir)+1:]
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
549
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
550 if css_files is None:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
551 css_files = self.getCSSFiles(template_path, template_root_dir)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
552
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
553 if css_inline:
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
554 css_contents = []
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
555 for css_file in css_files:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
556 css_file_path = os.path.join(template_root_dir, css_file)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
557 with open(css_file_path) as f:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
558 css_contents.append(f.read())
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
559 if css_contents:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
560 kwargs['css_content'] = '\n'.join(css_contents)
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
561
2265
322694543225 tools (common/template): ScriptsHandler fix/improvments:
Goffi <goffi@goffi.org>
parents: 2249
diff changeset
562 scripts_handler = ScriptsHandler(self, template_path, template_root_dir, root_path)
2249
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
563 self.setLocale(locale)
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
564 # XXX: theme used in template arguments is the requested theme, which may differ from actual theme
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
565 # if the template doesn't exist in the requested theme.
2394
7bfcc431f66d template: added media_path to template data
Goffi <goffi@goffi.org>
parents: 2391
diff changeset
566 return template_source.render(theme=theme, root_path=root_path, media_path=media_path, css_files=css_files, locale=self._locale, gidx=Indexer(), script=scripts_handler, **kwargs)