# HG changeset patch # User Goffi # Date 1520792280 -3600 # Node ID 00480cf83fa192f152d403e0f8c5a544ecbc65d5 # Parent 4440ea7047bdc138966c5c6d584ddd0c17a2deb7 template: added icon handling: 2 new methods can be used: - icon_defs to include definitions of svg icons - icon to use one previously declared svg plain svg is used instead of icon fonts to improve accessibility. diff -r 4440ea7047bd -r 00480cf83fa1 src/tools/common/template.py --- a/src/tools/common/template.py Fri Mar 02 17:53:31 2018 +0100 +++ b/src/tools/common/template.py Sun Mar 11 19:18:00 2018 +0100 @@ -50,6 +50,7 @@ from jinja2 import Markup as safe from jinja2 import is_undefined +from lxml import etree HTML_EXT = ('html', 'xhtml') DEFAULT_LOCALE = u'en_GB' @@ -221,6 +222,7 @@ self.env.filters['highlight'] = self.highlight # custom tests self.env.tests['in_the_past'] = self._in_the_past + self.icons_path = os.path.join(host.media_dir, u'fonts/fontello/svg') def installTranslations(self): i18n_dir = os.path.join(self.base_dir, 'i18n') @@ -567,9 +569,35 @@ """ return time.time() > int(timestamp) + ## template methods ## + + def _icon_defs(self, *names): + """Define svg icons which will be used in the template, and use their name as id""" + svg_elt = etree.Element('svg', nsmap={None: 'http://www.w3.org/2000/svg'}, + width='0', height='0', style='display: block' + ) + defs_elt = etree.SubElement(svg_elt, 'defs') + for name in names: + path = os.path.join(self.icons_path, name + u'.svg') + icon_svg_elt = etree.parse(path).getroot() + # we use icon name as id, so we can retrieve them easily + icon_svg_elt.set('id', name) + if not icon_svg_elt.tag == '{http://www.w3.org/2000/svg}svg': + raise exceptions.DataError(u'invalid SVG element') + defs_elt.append(icon_svg_elt) + return safe(etree.tostring(svg_elt, encoding='unicode')) + + def _icon_use(self, name, cls=''): + return safe(u""" + + + """.format( + name=name, + cls=(' ' + cls) if cls else '')) + def render(self, template, theme=None, locale=DEFAULT_LOCALE, root_path=u'', media_path=u'', css_files=None, css_inline=False, **kwargs): """render a template - +. @param template(unicode): template to render (e.g. blog/articles.html) @param theme(unicode): template theme @param root_path(unicode): prefix of the path/URL to use for template root @@ -603,6 +631,9 @@ if css_files is None: css_files = self.getCSSFiles(template_path, template_root_dir) + kwargs['icon_defs'] = self._icon_defs + kwargs['icon'] = self._icon_use + if css_inline: css_contents = [] for css_file in css_files: @@ -616,4 +647,7 @@ self.setLocale(locale) # XXX: theme used in template arguments is the requested theme, which may differ from actual theme # if the template doesn't exist in the requested theme. - 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) + 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)