comparison src/tools/common/template.py @ 2265:322694543225

tools (common/template): ScriptsHandler fix/improvments: ScriptsHandler was not used so far, this commit fix it to be usable: - script can be imported with "include" - generate_scripts is used to generate the <script> elements generation, in base page - paths use root_path, so they are adapted to context - generate_scripts return a Markup string, so it's not escaped
author Goffi <goffi@goffi.org>
date Sat, 24 Jun 2017 20:18:55 +0200
parents e572482f6cbd
children 084a75b8aa7a
comparison
equal deleted inserted replaced
2264:a8eaaac4d80f 2265:322694543225
23 from sat.core.i18n import _ 23 from sat.core.i18n import _
24 from sat.core import exceptions 24 from sat.core import exceptions
25 from sat.core.log import getLogger 25 from sat.core.log import getLogger
26 log = getLogger(__name__) 26 log = getLogger(__name__)
27 import os.path 27 import os.path
28 from collections import OrderedDict
29 from xml.sax.saxutils import quoteattr 28 from xml.sax.saxutils import quoteattr
30 import time 29 import time
31 from babel import support 30 from babel import support
32 from babel import Locale 31 from babel import Locale
33 from babel.core import UnknownLocaleError 32 from babel.core import UnknownLocaleError
40 39
41 try: 40 try:
42 import jinja2 41 import jinja2
43 except: 42 except:
44 raise exceptions.MissingModule(u'Missing module jinja2, please install it from http://jinja.pocoo.org or with pip install jinja2') 43 raise exceptions.MissingModule(u'Missing module jinja2, please install it from http://jinja.pocoo.org or with pip install jinja2')
44
45 from jinja2 import Markup as safe
45 46
46 HTML_EXT = ('html', 'xhtml') 47 HTML_EXT = ('html', 'xhtml')
47 DEFAULT_LOCALE = u'en' 48 DEFAULT_LOCALE = u'en'
48 # TODO: handle external path (an additional search path for templates should be settable by user 49 # TODO: handle external path (an additional search path for templates should be settable by user
49 # TODO: handle absolute URL (should be used for trusted use cases) only (e.g. jp) for security reason 50 # TODO: handle absolute URL (should be used for trusted use cases) only (e.g. jp) for security reason
134 def current(self): 135 def current(self):
135 return self._idx 136 return self._idx
136 137
137 138
138 class ScriptsHandler(object): 139 class ScriptsHandler(object):
139 # TODO: this class is not finished/used yet, and add_script is referenced in default/script/base.html 140
140 # but doesn't exist yet here 141 def __init__(self, renderer, template_path, template_root_dir, root_path):
141
142 def __init__(self, renderer, template_path, template_root_dir):
143 self.renderer = renderer 142 self.renderer = renderer
144 self.template_root_dir = template_root_dir 143 self.template_root_dir = template_root_dir
145 self.scripts = OrderedDict 144 self.root_path = root_path
145 self.scripts = [] # we don't use a set because order may be important
146 dummy, self.theme, self.is_default_theme = renderer.getThemeData(template_path) 146 dummy, self.theme, self.is_default_theme = renderer.getThemeData(template_path)
147 147
148 def import_script(self, library_name): 148 def include(self, library_name):
149 """Mark that a script need to be imported.
150
151 Must be used before base.html is extended, as <script> are generated there.
152 If called several time with the same library, it will be imported once.
153 @param library_name(unicode): name of the library to import
154 """
149 if library_name.endswith('.js'): 155 if library_name.endswith('.js'):
150 library_name = library_name[:-3] 156 library_name = library_name[:-3]
151 if library_name not in self.scripts: 157 if library_name not in self.scripts:
152 self.scripts[library_name] = {} 158 self.scripts.append(library_name)
153 159 return u''
154 def generate(self): 160
155 """Generate the <scripts> elements 161 def generate_scripts(self):
162 """Generate the <script> elements
163
156 @return (unicode): <scripts> HTML tags 164 @return (unicode): <scripts> HTML tags
157 """ 165 """
158 scripts = [] 166 scripts = []
159 tpl = u'<script src="{src}"></script>' 167 tpl = u'<script src={src}></script>'
160 for library,data in self.scripts: 168 for library in self.scripts:
161 path = self.renderer.getStaticPath(library, self.template_root_dir, self.theme, self.is_default_theme, '.js') 169 path = self.renderer.getStaticPath(library, self.template_root_dir, self.theme, self.is_default_theme, '.js')
162 if path is None: 170 if path is None:
163 log.warning(_(u"Can't find {}.js javascript library").format(library)) 171 log.warning(_(u"Can't find {}.js javascript library").format(library))
164 continue 172 continue
173 path = os.path.join(self.root_path, path)
165 scripts.append(tpl.format(src=quoteattr(path))) 174 scripts.append(tpl.format(src=quoteattr(path)))
166 return u'\n'.join(scripts) 175 return safe(u'\n'.join(scripts))
167 176
168 177
169 class Renderer(object): 178 class Renderer(object):
170 179
171 def __init__(self, host): 180 def __init__(self, host):
355 with open(css_file_path) as f: 364 with open(css_file_path) as f:
356 css_contents.append(f.read()) 365 css_contents.append(f.read())
357 if css_contents: 366 if css_contents:
358 kwargs['css_content'] = '\n'.join(css_contents) 367 kwargs['css_content'] = '\n'.join(css_contents)
359 368
360 scripts_handler = ScriptsHandler(self, template_path, template_root_dir) 369 scripts_handler = ScriptsHandler(self, template_path, template_root_dir, root_path)
361 self.setLocale(locale) 370 self.setLocale(locale)
362 # XXX: theme used in template arguments is the requested theme, which may differ from actual theme 371 # XXX: theme used in template arguments is the requested theme, which may differ from actual theme
363 # if the template doesn't exist in the requested theme. 372 # if the template doesn't exist in the requested theme.
364 return template_source.render(theme=theme, root_path=root_path, css_files=css_files, locale=locale, gidx=Indexer(), scripts_handler=scripts_handler, **kwargs) 373 return template_source.render(theme=theme, root_path=root_path, css_files=css_files, locale=self._locale, gidx=Indexer(), script=scripts_handler, **kwargs)