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.
This commit is contained in:
Goffi 2018-03-11 19:18:00 +01:00
commit 82b8250fac

View file

@ -50,6 +50,7 @@ except:
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 @@ class Renderer(object):
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 @@ class Renderer(object):
"""
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"""<svg class="svg-icon{cls}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<use href="#{name}"/>
</svg>
""".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 @@ class Renderer(object):
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 @@ class Renderer(object):
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)