annotate src/tools/common/template.py @ 2169:f472179305a1

tools(templates): workflow improvments: - template theme can be specified in parenthesis: (some_theme)path/to/template.html. Withtout parenthesis, "default" is used - static content are supposed to be in [theme]/static, error pages in [theme]/error/[err_code].html - default page are used in some case (2 for now): if error page with specified code doesn't exists, a base page is used, and if a page doesn't exist for a theme, the same one for default theme is looked for - CSS files are automatically found for HTML pages - CSS files can be split, the'll be added in the template according to the page requested. - theme CSS file is looked for, and if not found the default theme equivalent is looked for. - each element of a path can be associated to a CSS file, and styles.css is always there. For instance if blog/articles.html is requested, the following CSS can be included: "styles.css", "blog.css", "blog_article.css". They all must be in /static - if the automatic finding of CSS files is not wanted, css_files arguments can be used instead, with full relative path (i.e. including theme) - CSS files can be merged and included inline with css_inline argument - root_path can be specified, it will be used as a prefix for static files - requested theme (which may differ from actual theme, e.g. if the template is not found and default one is used instead) is available in template with "theme" variable - added getThemeAndRoot method to retrieve theme and theme root path from template
author Goffi <goffi@goffi.org>
date Sun, 05 Mar 2017 23:41:10 +0100
parents 5734b0994cf0
children e09048cb7595
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
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
5 # Copyright (C) 2009-2016 Jérôme Poisson (goffi@goffi.org)
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
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
23 from sat.core import exceptions
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
24 from sat.core.log import getLogger
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
25 log = getLogger(__name__)
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
26 import os.path
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
27 try:
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
28 import sat_templates
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
29 except ImportError:
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
30 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
31 else:
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
32 sat_templates # to avoid pyflakes warning
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
33
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
34 try:
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
35 import jinja2
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
36 except:
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
37 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
38
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
39 HTML_EXT = ('html', 'xhtml')
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
40 # 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
41 # 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
42
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
43
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
44 class TemplateLoader(jinja2.FileSystemLoader):
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
45
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
46 def __init__(self):
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
47 searchpath = os.path.dirname(sat_templates.__file__)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
48 super(TemplateLoader, self).__init__(searchpath, followlinks=True)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
49
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
50 def parse_template(self, template):
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
51 """parse template path and return theme and relative URL
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
52
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
53 @param template_path(unicode): path to template with parenthesis syntax
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
54 @return (tuple[(unicode,None),unicode]): theme and template_path
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
55 theme can be None if relative path is used
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
56 relative path is the path from search path with theme specified
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
57 e.g. default/blog/articles.html
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 if template.startswith(u'('):
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
60 try:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
61 theme_end = template.index(u')')
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
62 except IndexError:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
63 raise ValueError(u"incorrect theme in template")
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
64 theme = template[1:theme_end]
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
65 template = template[theme_end+1:]
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
66 if not template or template.startswith(u'/'):
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
67 raise ValueError(u"incorrect path after template name")
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
68 template = os.path.join(theme, template)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
69 elif template.startswith(u'/'):
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
70 # absolute path means no template
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
71 theme = None
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
72 raise NotImplementedError(u'absolute path is not implemented yet')
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
73 else:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
74 theme = C.TEMPLATE_THEME_DEFAULT
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
75 template = os.path.join(theme, template)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
76 return theme, template
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
77
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
78 def get_default_template(self, theme, template_path):
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
79 """return default template path
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
80
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
81 @param theme(unicode): theme used
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
82 @param template_path(unicode): path to the not found template
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
83 @return (unicode, None): default path or None if there is not
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
84 """
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
85 ext = os.path.splitext(template_path)[1][1:]
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
86 path_elems = template_path.split(u'/')
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
87 if ext in HTML_EXT:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
88 if path_elems[1] == u'error':
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
89 # if an inexisting error page is requested, we return base page
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
90 default_path = os.path.join(theme, u'error/base.html')
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
91 return default_path
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
92 if theme != C.TEMPLATE_THEME_DEFAULT:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
93 # 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
94 return os.path.join(C.TEMPLATE_THEME_DEFAULT, path_elems[1:])
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
95
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
96 def get_source(self, environment, template):
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
97 """relative path to template dir, with special theme handling
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
98
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
99 if the path is just relative, "default" theme is used.
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
100 The theme can be specified in parenthesis just before the path
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
101 e.g.: (some_theme)path/to/template.html
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
102 """
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
103 theme, template_path = self.parse_template(template)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
104 try:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
105 return super(TemplateLoader, self).get_source(environment, template_path)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
106 except jinja2.exceptions.TemplateNotFound as e:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
107 # 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
108 if theme is not None:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
109 default_path = self.get_default_template(theme, template_path)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
110 if default_path is not None:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
111 return super(TemplateLoader, self).get_source(environment, default_path)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
112 # if no default template is found, we re-raise the error
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
113 raise e
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
114
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
115
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
116 class Renderer(object):
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
117
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
118 def __init__(self, host):
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
119 self.host = host
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
120 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
121 self.env = jinja2.Environment(
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
122 loader=TemplateLoader(),
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
123 autoescape=jinja2.select_autoescape(['html', 'xhtml', 'xml']),
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
124 trim_blocks=True,
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
125 lstrip_blocks=True,
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
126 )
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
127 # 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
128 self.env.globals[u'C'] = C
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
129
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
130 def getThemeAndRoot(self, template):
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
131 """retrieve theme and root dir of a given tempalte
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
132
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
133 @param template(unicode): template to parse
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
134 @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
135 """
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
136 theme, dummy = self.env.loader.parse_template(template)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
137 return theme, os.path.join(self.base_dir, theme)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
138
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
139 def _appendCSSIfExists(self, css_files, template_root_dir, theme, name, is_default):
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
140 """append CSS file to list if it exists, else try with default theme
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
141
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
142 CSS file will be looked at [theme]/static/[name].css, and then default
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
143 if not found.
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
144 @param css_files(list): list of CSS file to be completed
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
145 @param template_root_dir(unicode): absolute path to template root used
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
146 @param theme(unicode): name of the template theme used
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
147 @param name(unicode): name of the CSS file to look for
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
148 @param is_default(bool): True if theme is the default theme
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
149 """
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
150 css_path = os.path.join(theme, C.TEMPLATE_STATIC_DIR, name + '.css')
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
151 if os.path.exists(os.path.join(template_root_dir, css_path)):
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
152 css_files.append(css_path)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
153 elif not is_default:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
154 css_path = os.path.join(C.TEMPLATE_THEME_DEFAULT, C.TEMPLATE_STATIC_DIR, name + '.css')
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
155 if os.path.exists(os.path.join(template_root_dir, css_path)):
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
156 css_files.append(css_path)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
157
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
158 def getCSSFiles(self, template_path, template_root_dir):
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
159 """retrieve CSS files to use according to theme and template path
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
160
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
161 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
162 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
163 For instance, if template_path is some_theme/blog/articles.html:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
164 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
165 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
166 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
167 @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
168 @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
169 @return list[unicode]: relative path to CSS files to use
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
170 """
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
171 # TODO: some caching would be nice
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
172 css_files = []
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
173 path_elems = template_path.split(u'/')
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
174 theme = path_elems.pop(0)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
175 is_default = theme == C.TEMPLATE_THEME_DEFAULT
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
176 self._appendCSSIfExists(css_files, template_root_dir, theme, u'styles', is_default)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
177
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
178 for idx, path in enumerate(path_elems):
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
179 self._appendCSSIfExists(css_files, template_root_dir, theme, u'_'.join(path_elems[:idx+1]), is_default)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
180
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
181 return css_files
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
182
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
183 def render(self, template, theme=None, root_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
184 """render a template
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
185
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
186 @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
187 @param theme(unicode): template theme
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
188 @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
189 must end with a u'/'
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
190 @param css_files(list[unicode],None): CSS files to used
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
191 CSS files must be in static dir of the template
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
192 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
193 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
194 @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
195 @param **kwargs: variable to transmit to the template
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
196 """
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
197 if not template:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
198 raise ValueError(u"template can't be empty")
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
199 if theme is not None:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
200 # 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
201 if template[0] == u'(':
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
202 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
203 elif template[0] == u'/':
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
204 raise ValueError(u"you can't specify theme with absolute paths")
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
205 template= u'(' + theme + u')' + template
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
206 else:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
207 theme, dummy = self.env.loader.parse_template(template)
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
208
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
209 template_source = self.env.get_template(template)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
210 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
211 # 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
212 template_path = template_source.filename[len(template_root_dir)+1:]
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
213
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
214 if css_files is None:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
215 css_files = self.getCSSFiles(template_path, template_root_dir)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
216
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
217 if css_inline:
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
218 css_contents = []
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
219 for css_file in css_files:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
220 css_file_path = os.path.join(template_root_dir, css_file)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
221 with open(css_file_path) as f:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
222 css_contents.append(f.read())
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
223 if css_contents:
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
224 kwargs['css_content'] = '\n'.join(css_contents)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
225 # 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
226 # if the template doesn't exist in the requested theme.
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
227 return template_source.render(theme=theme, root_path=root_path, css_files=css_files, **kwargs)