annotate libervia/backend/tools/common/template.py @ 4204:879bad48cc2d

frontends (tools/webrtc): implement X11 desktop sharing: rel 433
author Goffi <goffi@goffi.org>
date Tue, 16 Jan 2024 10:42:00 +0100
parents 81faa85c9cfa
children 0d7bb4df2343
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
1 #!/usr/bin/env python3
3137
559a625a236b fixed shebangs
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
2
3266
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
3 # SAT: an XMPP client
3479
be6d91572633 date update
Goffi <goffi@goffi.org>
parents: 3478
diff changeset
4 # Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org)
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
5
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
6 # 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
7 # 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
8 # 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
9 # (at your option) any later version.
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
10
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
11 # 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
12 # 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
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # GNU Affero General Public License for more details.
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
15
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
16 # 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
17 # 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
18
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
19 """Template generation"""
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
20
4089
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
21 from collections import namedtuple
4031
a2d4bd1943ba tools (common/template): add 2 new filters: `timestamp_to_hour` and `delta_to_human`:
Goffi <goffi@goffi.org>
parents: 4030
diff changeset
22 from datetime import datetime
4089
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
23 import html
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
24 import json
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
25 import os.path
3266
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
26 from pathlib import Path
4089
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
27 import re
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
28 import time
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
29 from typing import List, Optional, Tuple, Union
3266
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
30 from xml.sax.saxutils import quoteattr
4089
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
31
3266
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
32 from babel import support
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
33 from babel import Locale
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
34 from babel.core import UnknownLocaleError
4089
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
35 from jinja2 import is_undefined
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
36 from jinja2 import utils
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
37 from jinja2 import TemplateNotFound
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
38 from jinja2 import pass_context
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
39 from jinja2.loaders import split_template_path
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
40 from lxml import etree
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
41 from markupsafe import Markup as safe
3266
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
42 import pygments
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
43 from pygments import lexers
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
44 from pygments import formatters
4089
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
45
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
46 from libervia.backend.core import exceptions
4071
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
47 from libervia.backend.core.constants import Const as C
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
48 from libervia.backend.core.i18n import _
4089
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
49 from libervia.backend.core.log import getLogger
4071
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
50 from libervia.backend.tools import config
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
51 from libervia.backend.tools.common import date_utils
4165
81faa85c9cfa template: add a `bare_jid` filter
Goffi <goffi@goffi.org>
parents: 4100
diff changeset
52 from libervia.frontends.tools import jid
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
53
3038
5f3068915686 common (template): suppress jinja2 depreaction warning (to be removed once 2.10.1 is released)
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
54 log = getLogger(__name__)
5f3068915686 common (template): suppress jinja2 depreaction warning (to be removed once 2.10.1 is released)
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
55
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
56 try:
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
57 import sat_templates
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
58 except ImportError:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
59 raise exceptions.MissingModule(
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
60 "sat_templates module is not available, please install it or check your path to "
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
61 "use template engine"
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
62 )
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
63 else:
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
64 sat_templates # to avoid pyflakes warning
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
65
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
66 try:
3061
948833e3b542 tools (common/template): removed warning catches, jinja2>=2.10.3 now handles them correctly
Goffi <goffi@goffi.org>
parents: 3038
diff changeset
67 import jinja2
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
68 except:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
69 raise exceptions.MissingModule(
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
70 "Missing module jinja2, please install it from http://jinja.pocoo.org or with "
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
71 "pip install jinja2"
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
72 )
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
73
4089
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
74
2265
322694543225 tools (common/template): ScriptsHandler fix/improvments:
Goffi <goffi@goffi.org>
parents: 2249
diff changeset
75
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
76 HTML_EXT = ("html", "xhtml")
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
77 RE_ATTR_ESCAPE = re.compile(r"[^a-z_-]")
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
78 SITE_RESERVED_NAMES = ("sat",)
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
79 TPL_RESERVED_CHARS = r"()/."
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
80 RE_TPL_RESERVED_CHARS = re.compile("[" + TPL_RESERVED_CHARS + "]")
3266
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
81 BROWSER_DIR = "_browser"
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
82 BROWSER_META_FILE = "browser_meta.json"
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
83
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
84 TemplateData = namedtuple("TemplateData", ['site', 'theme', 'path'])
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
85
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
86
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
87 class TemplateLoader(jinja2.BaseLoader):
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
88 """A template loader which handle site, theme and absolute paths"""
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
89 # TODO: list_templates should be implemented
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
90
3478
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
91 def __init__(self, sites_paths, sites_themes, trusted=False):
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
92 """
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
93 @param trusted(bool): if True, absolue template paths will be allowed
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
94 be careful when using this option and sure that you can trust the template,
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
95 as this allow the template to open any file on the system that the
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
96 launching user can access.
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
97 """
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
98 if not sites_paths or not "" in sites_paths:
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
99 raise exceptions.InternalError("Invalid sites_paths")
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
100 super(jinja2.BaseLoader, self).__init__()
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
101 self.sites_paths = sites_paths
3478
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
102 self.sites_themes = sites_themes
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
103 self.trusted = trusted
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
104
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
105 @staticmethod
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
106 def parse_template(template):
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
107 """Parse template path and return site, theme and path
2169
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 @param template_path(unicode): path to template with parenthesis syntax
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
110 The site and/or theme can be specified in parenthesis just before the path
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
111 e.g.: (some_theme)path/to/template.html
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
112 (/some_theme)path/to/template.html (equivalent to previous one)
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
113 (other_site/other_theme)path/to/template.html
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
114 (other_site/)path/to/template.html (defaut theme for other_site)
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
115 /absolute/path/to/template.html (in trusted environment only)
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
116 @return (TemplateData):
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
117 site, theme and template_path.
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
118 if site is empty, SàT Templates are used
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
119 site and theme can be both None if absolute path is used
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
120 Relative path is the path from theme root dir e.g. blog/articles.html
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
121 """
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
122 if template.startswith("("):
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
123 # site and/or theme are specified
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
124 try:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
125 theme_end = template.index(")")
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
126 except IndexError:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
127 raise ValueError("incorrect site/theme in template")
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
128 theme_data = template[1:theme_end]
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
129 theme_splitted = theme_data.split('/')
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
130 if len(theme_splitted) == 1:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
131 site, theme = "", theme_splitted[0]
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
132 elif len(theme_splitted) == 2:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
133 site, theme = theme_splitted
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
134 else:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
135 raise ValueError("incorrect site/theme in template")
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
136 template_path = template[theme_end+1:]
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
137 if not template_path or template_path.startswith("/"):
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
138 raise ValueError("incorrect template path")
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
139 elif template.startswith("/"):
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
140 # this is an absolute path, so we have no site and no theme
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
141 site = None
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
142 theme = None
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
143 template_path = template
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
144 else:
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
145 # a default template
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
146 site = ""
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
147 theme = C.TEMPLATE_THEME_DEFAULT
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
148 template_path = template
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
149
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
150 if site is not None:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
151 site = site.strip()
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
152 if not site:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
153 site = ""
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
154 elif site in SITE_RESERVED_NAMES:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
155 raise ValueError(_("{site} can't be used as site name, "
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
156 "it's reserved.").format(site=site))
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
157
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
158 if theme is not None:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
159 theme = theme.strip()
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
160 if not theme:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
161 theme = C.TEMPLATE_THEME_DEFAULT
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
162 if RE_TPL_RESERVED_CHARS.search(theme):
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
163 raise ValueError(_("{theme} contain forbidden char. Following chars "
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
164 "are forbidden: {reserved}").format(
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
165 theme=theme, reserved=TPL_RESERVED_CHARS))
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
166
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
167 return TemplateData(site, theme, template_path)
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
168
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
169 @staticmethod
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4031
diff changeset
170 def get_sites_and_themes(
3268
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
171 site: str,
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
172 theme: str,
3478
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
173 settings: Optional[dict] = None,
3268
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
174 ) -> List[Tuple[str, str]]:
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
175 """Get sites and themes to check for template/file
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
176
3478
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
177 Will add default theme and default site in search list when suitable. Settings'
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
178 `fallback` can be used to modify behaviour: themes in this list will then be used
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
179 instead of default (it can also be empty list or None, in which case no fallback
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
180 is used).
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
181
3268
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
182 @param site: site requested
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
183 @param theme: theme requested
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
184 @return: site and theme couples to check
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
185 """
3478
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
186 if settings is None:
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
187 settings = {}
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
188 sites_and_themes = [[site, theme]]
3478
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
189 fallback = settings.get("fallback", [C.TEMPLATE_THEME_DEFAULT])
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
190 for fb_theme in fallback:
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
191 if theme != fb_theme:
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
192 sites_and_themes.append([site, fb_theme])
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
193 if site:
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
194 for fb_theme in fallback:
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
195 sites_and_themes.append(["", fb_theme])
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
196 return sites_and_themes
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
197
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
198 def _get_template_f(self, site, theme, path_elts):
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
199 """Look for template and return opened file if found
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
200
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
201 @param site(unicode): names of site to check
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
202 (default site will also checked)
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
203 @param theme(unicode): theme to check (default theme will also be checked)
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
204 @param path_elts(iterable[str]): elements of template path
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
205 @return (tuple[(File, None), (str, None)]): a tuple with:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
206 - opened template, or None if not found
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
207 - absolute file path, or None if not found
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
208 """
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
209 if site is None:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
210 raise exceptions.InternalError(
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
211 "_get_template_f must not be used with absolute path")
3478
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
212 settings = self.sites_themes[site][theme]['settings']
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4031
diff changeset
213 for site_to_check, theme_to_check in self.get_sites_and_themes(
3478
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
214 site, theme, settings):
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
215 try:
3478
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
216 base_path = self.sites_paths[site_to_check]
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
217 except KeyError:
3478
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
218 log.warning(_("Unregistered site requested: {site_to_check}").format(
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
219 site_to_check=site_to_check))
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
220 filepath = os.path.join(
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
221 base_path,
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
222 C.TEMPLATE_TPL_DIR,
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
223 theme_to_check,
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
224 *path_elts
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
225 )
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
226 f = utils.open_if_exists(filepath, 'r')
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
227 if f is not None:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
228 return f, filepath
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
229 return None, None
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
230
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
231 def get_source(self, environment, template):
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
232 """Retrieve source handling site and themes
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
233
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
234 If the path is absolute it is used directly if in trusted environment
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
235 else and exception is raised.
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
236 if the path is just relative, "default" theme is used.
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
237 @raise PermissionError: absolute path used in untrusted environment
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
238 """
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
239 site, theme, template_path = self.parse_template(template)
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
240
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
241 if site is None:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
242 # we have an abolute template
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
243 if theme is not None:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
244 raise exceptions.InternalError("We can't have a theme with absolute "
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
245 "template.")
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
246 if not self.trusted:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
247 log.error(_("Absolute template used while unsecure is disabled, hack "
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
248 "attempt? Template: {template}").format(template=template))
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
249 raise exceptions.PermissionError("absolute template is not allowed")
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
250 filepath = template_path
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
251 f = utils.open_if_exists(filepath, 'r')
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
252 else:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
253 # relative path, we have to deal with site and theme
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
254 assert theme and template_path
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
255 path_elts = split_template_path(template_path)
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
256 # if we have non default site, we check it first, else we only check default
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
257 f, filepath = self._get_template_f(site, theme, path_elts)
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
258
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
259 if f is None:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
260 if (site is not None and path_elts[0] == "error"
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
261 and os.path.splitext(template_path)[1][1:] in HTML_EXT):
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
262 # if an HTML error is requested but doesn't exist, we try again
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
263 # with base error.
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
264 f, filepath = self._get_template_f(
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
265 site, theme, ("error", "base.html"))
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
266 if f is None:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
267 raise exceptions.InternalError("error/base.html should exist")
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
268 else:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
269 raise TemplateNotFound(template)
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
270
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
271 try:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
272 contents = f.read()
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
273 finally:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
274 f.close()
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
275
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
276 mtime = os.path.getmtime(filepath)
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
277
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
278 def uptodate():
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
279 try:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
280 return os.path.getmtime(filepath) == mtime
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
281 except OSError:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
282 return False
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
283
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
284 return contents, filepath, uptodate
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
285
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
286
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
287 class Indexer(object):
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
288 """Index global to a page"""
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
289
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
290 def __init__(self):
2385
39d30cf722cb template: gidx methods improvment:
Goffi <goffi@goffi.org>
parents: 2384
diff changeset
291 self._indexes = {}
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
292
2385
39d30cf722cb template: gidx methods improvment:
Goffi <goffi@goffi.org>
parents: 2384
diff changeset
293 def next(self, value):
39d30cf722cb template: gidx methods improvment:
Goffi <goffi@goffi.org>
parents: 2384
diff changeset
294 if value not in self._indexes:
39d30cf722cb template: gidx methods improvment:
Goffi <goffi@goffi.org>
parents: 2384
diff changeset
295 self._indexes[value] = 0
39d30cf722cb template: gidx methods improvment:
Goffi <goffi@goffi.org>
parents: 2384
diff changeset
296 return 0
39d30cf722cb template: gidx methods improvment:
Goffi <goffi@goffi.org>
parents: 2384
diff changeset
297 self._indexes[value] += 1
39d30cf722cb template: gidx methods improvment:
Goffi <goffi@goffi.org>
parents: 2384
diff changeset
298 return self._indexes[value]
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
299
2385
39d30cf722cb template: gidx methods improvment:
Goffi <goffi@goffi.org>
parents: 2384
diff changeset
300 def current(self, value):
39d30cf722cb template: gidx methods improvment:
Goffi <goffi@goffi.org>
parents: 2384
diff changeset
301 return self._indexes.get(value)
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
302
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
303
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
304 class ScriptsHandler(object):
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
305 def __init__(self, renderer, template_data):
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
306 self.renderer = renderer
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
307 self.template_data = template_data
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
308 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
309
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
310 def include(self, library_name, attribute="defer"):
2265
322694543225 tools (common/template): ScriptsHandler fix/improvments:
Goffi <goffi@goffi.org>
parents: 2249
diff changeset
311 """Mark that a script need to be imported.
322694543225 tools (common/template): ScriptsHandler fix/improvments:
Goffi <goffi@goffi.org>
parents: 2249
diff changeset
312
322694543225 tools (common/template): ScriptsHandler fix/improvments:
Goffi <goffi@goffi.org>
parents: 2249
diff changeset
313 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
314 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
315 @param library_name(unicode): name of the library to import
2465
bb0bbcc80fc8 template: boolean attribute can now be specified when importing a script, and default to "defer"
Goffi <goffi@goffi.org>
parents: 2454
diff changeset
316 @param loading:
2265
322694543225 tools (common/template): ScriptsHandler fix/improvments:
Goffi <goffi@goffi.org>
parents: 2249
diff changeset
317 """
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
318 if attribute not in ("defer", "async", ""):
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
319 raise exceptions.DataError(
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
320 _('Invalid attribute, please use one of "defer", "async" or ""')
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
321 )
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
322 if not library_name.endswith(".js"):
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
323 library_name = library_name + ".js"
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
324 if (library_name, attribute) not in self.scripts:
2465
bb0bbcc80fc8 template: boolean attribute can now be specified when importing a script, and default to "defer"
Goffi <goffi@goffi.org>
parents: 2454
diff changeset
325 self.scripts.append((library_name, attribute))
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
326 return ""
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
327
2265
322694543225 tools (common/template): ScriptsHandler fix/improvments:
Goffi <goffi@goffi.org>
parents: 2249
diff changeset
328 def generate_scripts(self):
322694543225 tools (common/template): ScriptsHandler fix/improvments:
Goffi <goffi@goffi.org>
parents: 2249
diff changeset
329 """Generate the <script> elements
322694543225 tools (common/template): ScriptsHandler fix/improvments:
Goffi <goffi@goffi.org>
parents: 2249
diff changeset
330
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
331 @return (unicode): <scripts> HTML tags
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
332 """
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
333 scripts = []
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
334 tpl = "<script src={src} {attribute}></script>"
2465
bb0bbcc80fc8 template: boolean attribute can now be specified when importing a script, and default to "defer"
Goffi <goffi@goffi.org>
parents: 2454
diff changeset
335 for library, attribute in self.scripts:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4031
diff changeset
336 library_path = self.renderer.get_static_path(self.template_data, library)
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
337 if library_path is None:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
338 log.warning(_("Can't find {libary} javascript library").format(
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
339 library=library))
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
340 continue
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4031
diff changeset
341 path = self.renderer.get_front_url(library_path)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
342 scripts.append(tpl.format(src=quoteattr(path), attribute=attribute))
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
343 return safe("\n".join(scripts))
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
344
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
345
2676
da8f3ac86845 template: overriden get_template to always have full template name:
Goffi <goffi@goffi.org>
parents: 2675
diff changeset
346 class Environment(jinja2.Environment):
da8f3ac86845 template: overriden get_template to always have full template name:
Goffi <goffi@goffi.org>
parents: 2675
diff changeset
347
da8f3ac86845 template: overriden get_template to always have full template name:
Goffi <goffi@goffi.org>
parents: 2675
diff changeset
348 def get_template(self, name, parent=None, globals=None):
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
349 if name[0] not in ('/', '('):
2676
da8f3ac86845 template: overriden get_template to always have full template name:
Goffi <goffi@goffi.org>
parents: 2675
diff changeset
350 # if name is not an absolute path or a full template name (this happen on
da8f3ac86845 template: overriden get_template to always have full template name:
Goffi <goffi@goffi.org>
parents: 2675
diff changeset
351 # extend or import during rendering), we convert it to a full template name.
da8f3ac86845 template: overriden get_template to always have full template name:
Goffi <goffi@goffi.org>
parents: 2675
diff changeset
352 # This is needed to handle cache correctly when a base template is overriden.
da8f3ac86845 template: overriden get_template to always have full template name:
Goffi <goffi@goffi.org>
parents: 2675
diff changeset
353 # Without that, we could not distinguish something like base/base.html if
da8f3ac86845 template: overriden get_template to always have full template name:
Goffi <goffi@goffi.org>
parents: 2675
diff changeset
354 # it's launched from some_site/some_theme or from [default]/default
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
355 name = "({site}/{theme}){template}".format(
2676
da8f3ac86845 template: overriden get_template to always have full template name:
Goffi <goffi@goffi.org>
parents: 2675
diff changeset
356 site=self._template_data.site,
da8f3ac86845 template: overriden get_template to always have full template name:
Goffi <goffi@goffi.org>
parents: 2675
diff changeset
357 theme=self._template_data.theme,
da8f3ac86845 template: overriden get_template to always have full template name:
Goffi <goffi@goffi.org>
parents: 2675
diff changeset
358 template=name)
da8f3ac86845 template: overriden get_template to always have full template name:
Goffi <goffi@goffi.org>
parents: 2675
diff changeset
359
da8f3ac86845 template: overriden get_template to always have full template name:
Goffi <goffi@goffi.org>
parents: 2675
diff changeset
360 return super(Environment, self).get_template(name, parent, globals)
da8f3ac86845 template: overriden get_template to always have full template name:
Goffi <goffi@goffi.org>
parents: 2675
diff changeset
361
da8f3ac86845 template: overriden get_template to always have full template name:
Goffi <goffi@goffi.org>
parents: 2675
diff changeset
362
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
363 class Renderer(object):
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
364
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
365 def __init__(self, host, front_url_filter=None, trusted=False, private=False):
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
366 """
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
367 @param front_url_filter(callable): filter to retrieve real url of a directory/file
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
368 The callable will get a two arguments:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
369 - a dict with a "template_data" key containing TemplateData instance of
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
370 current template. Only site and theme should be necessary.
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
371 - the relative URL of the file to retrieve, relative from theme root
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
372 None to use default filter which return real path on file
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
373 Need to be specified for web rendering, to reflect URL seen by end user
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
374 @param trusted(bool): if True, allow to access absolute path
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
375 Only set to True if environment is safe (e.g. command line tool)
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
376 @param private(bool): if True, also load sites from sites_path_private_dict
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
377 """
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
378 self.host = host
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
379 self.trusted = trusted
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
380 self.sites_paths = {
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
381 "": os.path.dirname(sat_templates.__file__),
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
382 }
3266
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
383 self.sites_themes = {
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
384 }
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4031
diff changeset
385 conf = config.parse_main_conf()
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4031
diff changeset
386 public_sites = config.config_get(conf, None, "sites_path_public_dict", {})
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
387 sites_data = [public_sites]
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
388 if private:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4031
diff changeset
389 private_sites = config.config_get(conf, None, "sites_path_private_dict", {})
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
390 sites_data.append(private_sites)
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
391 for sites in sites_data:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
392 normalised = {}
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
393 for name, path in sites.items():
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
394 if RE_TPL_RESERVED_CHARS.search(name):
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
395 log.warning(_("Can't add \"{name}\" site, it contains forbidden "
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
396 "characters. Forbidden characters are {forbidden}.")
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
397 .format(name=name, forbidden=TPL_RESERVED_CHARS))
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
398 continue
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
399 path = os.path.expanduser(os.path.normpath(path))
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
400 if not path or not path.startswith("/"):
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
401 log.warning(_("Can't add \"{name}\" site, it should map to an "
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
402 "absolute path").format(name=name))
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
403 continue
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
404 normalised[name] = path
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
405 self.sites_paths.update(normalised)
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
406
3266
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
407 for site, site_path in self.sites_paths.items():
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
408 tpl_path = Path(site_path) / C.TEMPLATE_TPL_DIR
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
409 for p in tpl_path.iterdir():
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
410 if not p.is_dir():
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
411 continue
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
412 log.debug(f"theme found for {site or 'default site'}: {p.name}")
3268
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
413 theme_data = self.sites_themes.setdefault(site, {})[p.name] = {
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
414 'path': p,
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
415 'settings': {}}
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
416 theme_settings = p / "settings.json"
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
417 if theme_settings.is_file:
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
418 try:
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
419 with theme_settings.open() as f:
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
420 settings = json.load(f)
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
421 except Exception as e:
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
422 log.warning(_(
3478
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
423 "Can't load theme settings at {path}: {e}").format(
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
424 path=theme_settings, e=e))
3268
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
425 else:
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
426 log.debug(
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
427 f"found settings for theme {p.name!r} at {theme_settings}")
3478
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
428 fallback = settings.get("fallback")
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
429 if fallback is None:
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
430 settings["fallback"] = []
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
431 elif isinstance(fallback, str):
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
432 settings["fallback"] = [fallback]
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
433 elif not isinstance(fallback, list):
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
434 raise ValueError(
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
435 'incorrect type for "fallback" in settings '
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
436 f'({type(fallback)}) at {theme_settings}: {fallback}'
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
437 )
3268
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
438 theme_data['settings'] = settings
3266
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
439 browser_path = p / BROWSER_DIR
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
440 if browser_path.is_dir():
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
441 theme_data['browser_path'] = browser_path
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
442 browser_meta_path = browser_path / BROWSER_META_FILE
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
443 if browser_meta_path.is_file():
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
444 try:
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
445 with browser_meta_path.open() as f:
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
446 theme_data['browser_meta'] = json.load(f)
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
447 except Exception as e:
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
448 log.error(
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
449 f"Can't parse browser metadata at {browser_meta_path}: {e}"
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
450 )
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
451 continue
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
452
2676
da8f3ac86845 template: overriden get_template to always have full template name:
Goffi <goffi@goffi.org>
parents: 2675
diff changeset
453 self.env = Environment(
3478
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
454 loader=TemplateLoader(
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
455 sites_paths=self.sites_paths,
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
456 sites_themes=self.sites_themes,
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
457 trusted=trusted
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
458 ),
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
459 autoescape=jinja2.select_autoescape(["html", "xhtml", "xml"]),
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
460 trim_blocks=True,
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
461 lstrip_blocks=True,
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
462 extensions=["jinja2.ext.i18n"],
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
463 )
2676
da8f3ac86845 template: overriden get_template to always have full template name:
Goffi <goffi@goffi.org>
parents: 2675
diff changeset
464 self.env._template_data = None
2599
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
465 self._locale_str = C.DEFAULT_LOCALE
2249
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
466 self._locale = Locale.parse(self._locale_str)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4031
diff changeset
467 self.install_translations()
2906
7dbdbd132649 template (i18n): activate ext.i18n.trimmed policy, to have clean translation strings. Set minimal jinja2 version to 2.10
Goffi <goffi@goffi.org>
parents: 2903
diff changeset
468
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
469 # we want to have access to SàT constants in templates
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
470 self.env.globals["C"] = C
2906
7dbdbd132649 template (i18n): activate ext.i18n.trimmed policy, to have clean translation strings. Set minimal jinja2 version to 2.10
Goffi <goffi@goffi.org>
parents: 2903
diff changeset
471
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
472 # custom filters
4165
81faa85c9cfa template: add a `bare_jid` filter
Goffi <goffi@goffi.org>
parents: 4100
diff changeset
473 self.env.filters["bare_jid"] = self._bare_jid
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
474 self.env.filters["next_gidx"] = self._next_gidx
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
475 self.env.filters["cur_gidx"] = self._cur_gidx
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
476 self.env.filters["date_fmt"] = self._date_fmt
4031
a2d4bd1943ba tools (common/template): add 2 new filters: `timestamp_to_hour` and `delta_to_human`:
Goffi <goffi@goffi.org>
parents: 4030
diff changeset
477 self.env.filters["timestamp_to_hour"] = self._timestamp_to_hour
a2d4bd1943ba tools (common/template): add 2 new filters: `timestamp_to_hour` and `delta_to_human`:
Goffi <goffi@goffi.org>
parents: 4030
diff changeset
478 self.env.filters["delta_to_human"] = date_utils.delta2human
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
479 self.env.filters["xmlui_class"] = self._xmlui_class
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
480 self.env.filters["attr_escape"] = self.attr_escape
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
481 self.env.filters["item_filter"] = self._item_filter
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
482 self.env.filters["adv_format"] = self._adv_format
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
483 self.env.filters["dict_ext"] = self._dict_ext
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
484 self.env.filters["highlight"] = self.highlight
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
485 self.env.filters["front_url"] = (self._front_url if front_url_filter is None
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
486 else front_url_filter)
4100
810921c33a47 tools (common/template): add filter to get media types:
Goffi <goffi@goffi.org>
parents: 4089
diff changeset
487 self.env.filters["media_type_main"] = self.media_type_main
810921c33a47 tools (common/template): add filter to get media types:
Goffi <goffi@goffi.org>
parents: 4089
diff changeset
488 self.env.filters["media_type_sub"] = self.media_type_sub
2403
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
489 # custom tests
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
490 self.env.tests["in_the_past"] = self._in_the_past
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
491 self.icons_path = os.path.join(host.media_dir, "fonts/fontello/svg")
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
492
2906
7dbdbd132649 template (i18n): activate ext.i18n.trimmed policy, to have clean translation strings. Set minimal jinja2 version to 2.10
Goffi <goffi@goffi.org>
parents: 2903
diff changeset
493 # policies
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
494 self.env.policies["ext.i18n.trimmed"] = True
3306
3af0909629a2 common (template): better json dumping:
Goffi <goffi@goffi.org>
parents: 3274
diff changeset
495 self.env.policies["json.dumps_kwargs"] = {
3af0909629a2 common (template): better json dumping:
Goffi <goffi@goffi.org>
parents: 3274
diff changeset
496 "sort_keys": True,
3af0909629a2 common (template): better json dumping:
Goffi <goffi@goffi.org>
parents: 3274
diff changeset
497 # if object can't be serialised, we use None
3311
29f8122f00f3 tools (common/template): use `to_json` instead of `json` + added missing args to `date_fmt`
Goffi <goffi@goffi.org>
parents: 3306
diff changeset
498 "default": lambda o: o.to_json() if hasattr(o, "to_json") else None
3306
3af0909629a2 common (template): better json dumping:
Goffi <goffi@goffi.org>
parents: 3274
diff changeset
499 }
2906
7dbdbd132649 template (i18n): activate ext.i18n.trimmed policy, to have clean translation strings. Set minimal jinja2 version to 2.10
Goffi <goffi@goffi.org>
parents: 2903
diff changeset
500
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4031
diff changeset
501 def get_front_url(self, template_data, path=None):
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
502 """Give front URL (i.e. URL seen by end-user) of a path
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
503
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
504 @param template_data[TemplateData]: data of current template
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
505 @param path(unicode, None): relative path of file to get,
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
506 if set, will remplate template_data.path
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
507 """
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
508 return self.env.filters["front_url"]({"template_data": template_data},
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
509 path or template_data.path)
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
510
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4031
diff changeset
511 def install_translations(self):
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
512 # TODO: support multi translation
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
513 # for now, only translations in sat_templates are handled
2903
68a7543ebbb3 template: added "locales" variables to templates:
Goffi <goffi@goffi.org>
parents: 2877
diff changeset
514 self.translations = {}
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
515 for site_key, site_path in self.sites_paths.items():
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
516 site_prefix = "[{}] ".format(site_key) if site_key else ''
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
517 i18n_dir = os.path.join(site_path, "i18n")
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
518 for lang_dir in os.listdir(i18n_dir):
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
519 lang_path = os.path.join(i18n_dir, lang_dir)
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
520 if not os.path.isdir(lang_path):
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
521 continue
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
522 po_path = os.path.join(lang_path, "LC_MESSAGES/sat.mo")
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
523 try:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
524 locale = Locale.parse(lang_dir)
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
525 with open(po_path, "rb") as f:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
526 try:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
527 translations = self.translations[locale]
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
528 except KeyError:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
529 self.translations[locale] = support.Translations(f, "sat")
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
530 else:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
531 translations.merge(support.Translations(f, "sat"))
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
532 except EnvironmentError:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
533 log.error(
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
534 _("Can't find template translation at {path}").format(
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
535 path=po_path))
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
536 except UnknownLocaleError as e:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
537 log.error(_("{site}Invalid locale name: {msg}").format(
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
538 site=site_prefix, msg=e))
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
539 else:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
540 log.info(_("{site}loaded {lang} templates translations").format(
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
541 site = site_prefix,
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
542 lang=lang_dir))
2903
68a7543ebbb3 template: added "locales" variables to templates:
Goffi <goffi@goffi.org>
parents: 2877
diff changeset
543
68a7543ebbb3 template: added "locales" variables to templates:
Goffi <goffi@goffi.org>
parents: 2877
diff changeset
544 default_locale = Locale.parse(self._locale_str)
68a7543ebbb3 template: added "locales" variables to templates:
Goffi <goffi@goffi.org>
parents: 2877
diff changeset
545 if default_locale not in self.translations:
68a7543ebbb3 template: added "locales" variables to templates:
Goffi <goffi@goffi.org>
parents: 2877
diff changeset
546 # default locale disable gettext,
68a7543ebbb3 template: added "locales" variables to templates:
Goffi <goffi@goffi.org>
parents: 2877
diff changeset
547 # so we can use None instead of a Translations instance
68a7543ebbb3 template: added "locales" variables to templates:
Goffi <goffi@goffi.org>
parents: 2877
diff changeset
548 self.translations[default_locale] = None
68a7543ebbb3 template: added "locales" variables to templates:
Goffi <goffi@goffi.org>
parents: 2877
diff changeset
549
68a7543ebbb3 template: added "locales" variables to templates:
Goffi <goffi@goffi.org>
parents: 2877
diff changeset
550 self.env.install_null_translations(True)
68a7543ebbb3 template: added "locales" variables to templates:
Goffi <goffi@goffi.org>
parents: 2877
diff changeset
551 # we generate a tuple of locales ordered by display name that templates can access
68a7543ebbb3 template: added "locales" variables to templates:
Goffi <goffi@goffi.org>
parents: 2877
diff changeset
552 # through the "locales" variable
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
553 self.locales = tuple(sorted(list(self.translations.keys()),
2903
68a7543ebbb3 template: added "locales" variables to templates:
Goffi <goffi@goffi.org>
parents: 2877
diff changeset
554 key=lambda l: l.language_name.lower()))
68a7543ebbb3 template: added "locales" variables to templates:
Goffi <goffi@goffi.org>
parents: 2877
diff changeset
555
2249
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
556
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4031
diff changeset
557 def set_locale(self, locale_str):
2403
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
558 """set current locale
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
559
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
560 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
561 """
2249
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
562 if locale_str == self._locale_str:
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
563 return
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
564 if locale_str == "en":
2403
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
565 # we default to GB English when it's not specified
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
566 # one of the main reason is to avoid the nonsense U.S. short date format
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
567 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
568 try:
2dae79990122 template: print warning message and use DEFAULT_LOCALE on bad locale
Goffi <goffi@goffi.org>
parents: 2266
diff changeset
569 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
570 except ValueError as e:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
571 log.warning(_("invalid locale value: {msg}").format(msg=e))
2599
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
572 locale_str = self._locale_str = C.DEFAULT_LOCALE
2323
2dae79990122 template: print warning message and use DEFAULT_LOCALE on bad locale
Goffi <goffi@goffi.org>
parents: 2266
diff changeset
573 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
574
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
575 locale_str = str(locale)
2599
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
576 if locale_str != C.DEFAULT_LOCALE:
2249
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
577 try:
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
578 translations = self.translations[locale]
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
579 except KeyError:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
580 log.warning(_("Can't find locale {locale}".format(locale=locale)))
2599
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
581 locale_str = C.DEFAULT_LOCALE
2249
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
582 locale = Locale.parse(self._locale_str)
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
583 else:
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
584 self.env.install_gettext_translations(translations, True)
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
585 log.debug(_("Switched to {lang}").format(lang=locale.english_name))
2249
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
586
2599
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
587 if locale_str == C.DEFAULT_LOCALE:
2249
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
588 self.env.install_null_translations(True)
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
589
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
590 self._locale = locale
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
591 self._locale_str = locale_str
e572482f6cbd core (tools/common/template): i18n support
Goffi <goffi@goffi.org>
parents: 2245
diff changeset
592
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4031
diff changeset
593 def get_theme_and_root(self, template):
3478
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
594 """retrieve theme and root dir of a given template
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
595
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
596 @param template(unicode): template to parse
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
597 @return (tuple[unicode, unicode]): theme and absolute path to theme's root dir
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
598 @raise NotFound: requested site has not been found
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
599 """
4075
47401850dec6 refactoring: rename `libervia.frontends.jp` to `libervia.cli`
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
600 # FIXME: check use in CLI frontend, and include site
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
601 site, theme, __ = self.env.loader.parse_template(template)
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
602 if site is None:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
603 # absolute template
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
604 return "", os.path.dirname(template)
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
605 try:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
606 site_root_dir = self.sites_paths[site]
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
607 except KeyError:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
608 raise exceptions.NotFound
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
609 return theme, os.path.join(site_root_dir, C.TEMPLATE_TPL_DIR, theme)
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
610
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4031
diff changeset
611 def get_themes_data(self, site_name):
3266
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
612 try:
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
613 return self.sites_themes[site_name]
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
614 except KeyError:
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
615 raise exceptions.NotFound(f"no theme found for {site_name}")
8ec5ddb4e759 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method
Goffi <goffi@goffi.org>
parents: 3137
diff changeset
616
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4031
diff changeset
617 def get_static_path(
3268
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
618 self,
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
619 template_data: TemplateData,
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
620 filename: str,
3478
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
621 settings: Optional[dict]=None
3268
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
622 ) -> Optional[TemplateData]:
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
623 """Retrieve path of a static file if it exists with current theme or default
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
624
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
625 File will be looked at <site_root_dir>/<theme_dir>/<static_dir>/filename,
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
626 then <site_root_dir>/<default_theme_dir>/<static_dir>/filename anf finally
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
627 <default_site>/<default_theme_dir>/<static_dir> (i.e. sat_templates).
3268
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
628 In case of absolute URL, base dir of template is used as base. For instance if
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
629 template is an absolute template to "/some/path/template.html", file will be
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
630 checked at "/some/path/<filename>"
3268
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
631 @param template_data: data of current template
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
632 @param filename: name of the file to retrieve
3478
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
633 @param settings: theme settings, can be used to modify behaviour
3268
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
634 @return: built template data instance where .path is
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
635 the relative path to the file, from theme root dir.
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
636 None if not found.
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
637 """
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
638 if template_data.site is None:
3268
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
639 # we have an absolue path
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
640 if (not template_data.theme is None
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
641 or not template_data.path.startswith('/')):
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
642 raise exceptions.InternalError(
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
643 "invalid template data, was expecting absolute URL")
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
644 static_dir = os.path.dirname(template_data.path)
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
645 file_path = os.path.join(static_dir, filename)
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
646 if os.path.exists(file_path):
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
647 return TemplateData(site=None, theme=None, path=file_path)
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
648 else:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
649 return None
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
650
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4031
diff changeset
651 sites_and_themes = TemplateLoader.get_sites_and_themes(template_data.site,
3268
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
652 template_data.theme,
3478
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
653 settings)
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
654 for site, theme in sites_and_themes:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
655 site_root_dir = self.sites_paths[site]
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
656 relative_path = os.path.join(C.TEMPLATE_STATIC_DIR, filename)
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
657 absolute_path = os.path.join(site_root_dir, C.TEMPLATE_TPL_DIR,
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
658 theme, relative_path)
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
659 if os.path.exists(absolute_path):
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
660 return TemplateData(site=site, theme=theme, path=relative_path)
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
661
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
662 return None
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
663
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4031
diff changeset
664 def _append_css_paths(
3268
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
665 self,
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
666 template_data: TemplateData,
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
667 css_files: list,
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
668 css_files_noscript: list,
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
669 name_root: str,
3478
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
670 settings: dict
3268
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
671
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
672 ) -> None:
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
673 """Append found css to css_files and css_files_noscript
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
674
3268
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
675 @param css_files: list to fill of relative path to found css file
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
676 @param css_files_noscript: list to fill of relative path to found css file
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
677 with "_noscript" suffix
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
678 """
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
679 name = name_root + ".css"
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4031
diff changeset
680 css_path = self.get_static_path(template_data, name, settings)
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
681 if css_path is not None:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4031
diff changeset
682 css_files.append(self.get_front_url(css_path))
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
683 noscript_name = name_root + "_noscript.css"
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4031
diff changeset
684 noscript_path = self.get_static_path(
3478
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
685 template_data, noscript_name, settings)
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
686 if noscript_path is not None:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4031
diff changeset
687 css_files_noscript.append(self.get_front_url(noscript_path))
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
688
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4031
diff changeset
689 def get_css_files(self, template_data):
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
690 """Retrieve CSS files to use according template_data
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
691
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
692 For each element of the path, a .css file is looked for in /static, and returned
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
693 if it exists.
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
694 Previous element are kept by replacing '/' with '_'.
2877
f8427bf8c072 tools (common/template): always use highlight.css if present.
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
695 styles_extra.css, styles.css, highlight.css and fonts.css are always used if they
f8427bf8c072 tools (common/template): always use highlight.css if present.
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
696 exist.
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
697 For each found file, if a file with the same name and "_noscript" suffix exists,
3267
2eeca6fd08f7 tools (common/template): typos
Goffi <goffi@goffi.org>
parents: 3266
diff changeset
698 it will be returned is second part of resulting tuple.
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
699 For instance, if template_data is (some_site, some_theme, blog/articles.html),
3267
2eeca6fd08f7 tools (common/template): typos
Goffi <goffi@goffi.org>
parents: 3266
diff changeset
700 following files are returned, each time trying [some_site root] first,
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
701 then default site (i.e. sat_templates) root:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
702 - some_theme/static/styles.css is returned if it exists
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
703 else default/static/styles.css
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
704 - some_theme/static/blog.css is returned if it exists
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
705 else default/static/blog.css (if it exists too)
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
706 - some_theme/static/blog_articles.css is returned if it exists
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
707 else default/static/blog_articles.css (if it exists too)
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
708 and for each found files, if same file with _noscript suffix exists, it is put
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
709 in noscript list (for instance (some_theme/static/styles_noscript.css)).
3478
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
710 The behaviour may be changed with theme settings: if "fallback" is set, specified
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
711 themes will be checked instead of default. The theme will be checked in given
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
712 order, and "fallback" may be None or empty list to not check anything.
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
713 @param template_data(TemplateData): data of the current template
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
714 @return (tuple[list[unicode], list[unicode]]): a tuple with:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
715 - front URLs of CSS files to use
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
716 - front URLs of CSS files to use when scripts are not enabled
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
717 """
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
718 # TODO: some caching would be nice
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
719 css_files = []
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
720 css_files_noscript = []
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
721 path_elems = template_data.path.split('/')
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
722 path_elems[-1] = os.path.splitext(path_elems[-1])[0]
3268
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
723 site = template_data.site
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
724 if site is None:
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
725 # absolute path
3478
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
726 settings = {}
3268
85c9cfcd4f5e tools (common/template): theme settings with possibility to disable default fallback for CSS:
Goffi <goffi@goffi.org>
parents: 3267
diff changeset
727 else:
3478
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
728 settings = self.sites_themes[site][template_data.theme]['settings']
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
729
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4031
diff changeset
730 css_path = self.get_static_path(template_data, 'fonts.css', settings)
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
731 if css_path is not None:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4031
diff changeset
732 css_files.append(self.get_front_url(css_path))
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
733
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
734 for name_root in ('styles', 'styles_extra', 'highlight'):
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4031
diff changeset
735 self._append_css_paths(
3478
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
736 template_data, css_files, css_files_noscript, name_root, settings)
2683
38af118a7d74 template: better css files order
Goffi <goffi@goffi.org>
parents: 2680
diff changeset
737
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
738 for idx in range(len(path_elems)):
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
739 name_root = "_".join(path_elems[:idx+1])
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4031
diff changeset
740 self._append_css_paths(
3478
b65175eb7769 tools (common/template): new `fallback` settings:
Goffi <goffi@goffi.org>
parents: 3311
diff changeset
741 template_data, css_files, css_files_noscript, name_root, settings)
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
742
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
743 return css_files, css_files_noscript
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
744
2403
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
745 ## custom filters ##
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
746
4081
84f6bee6440d installation: moved from `setup.py` to `pyproject.toml`:
Goffi <goffi@goffi.org>
parents: 4075
diff changeset
747 @pass_context
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
748 def _front_url(self, ctx, relative_url):
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
749 """Get front URL (URL seen by end-user) from a relative URL
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
750
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
751 This default method return absolute full path
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
752 """
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
753 template_data = ctx['template_data']
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
754 if template_data.site is None:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
755 assert template_data.theme is None
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
756 assert template_data.path.startswith("/")
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
757 return os.path.join(os.path.dirname(template_data.path, relative_url))
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
758
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
759 site_root_dir = self.sites_paths[template_data.site]
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
760 return os.path.join(site_root_dir, C.TEMPLATE_TPL_DIR, template_data.theme,
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
761 relative_url)
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
762
4165
81faa85c9cfa template: add a `bare_jid` filter
Goffi <goffi@goffi.org>
parents: 4100
diff changeset
763 def _bare_jid(self, full_jid: str|jid.JID) -> str:
81faa85c9cfa template: add a `bare_jid` filter
Goffi <goffi@goffi.org>
parents: 4100
diff changeset
764 """Return the bare JID"""
81faa85c9cfa template: add a `bare_jid` filter
Goffi <goffi@goffi.org>
parents: 4100
diff changeset
765 return str(jid.JID(str(full_jid)).bare)
81faa85c9cfa template: add a `bare_jid` filter
Goffi <goffi@goffi.org>
parents: 4100
diff changeset
766
4081
84f6bee6440d installation: moved from `setup.py` to `pyproject.toml`:
Goffi <goffi@goffi.org>
parents: 4075
diff changeset
767 @pass_context
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
768 def _next_gidx(self, ctx, value):
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
769 """Use next current global index as suffix"""
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
770 next_ = ctx["gidx"].next(value)
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
771 return value if next_ == 0 else "{}_{}".format(value, next_)
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
772
4081
84f6bee6440d installation: moved from `setup.py` to `pyproject.toml`:
Goffi <goffi@goffi.org>
parents: 4075
diff changeset
773 @pass_context
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
774 def _cur_gidx(self, ctx, value):
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
775 """Use current current global index as suffix"""
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
776 current = ctx["gidx"].current(value)
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
777 return value if not current else "{}_{}".format(value, current)
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
778
4030
73936abc6838 tools (common/template): let specify timezone name in `date_fmt` filter
Goffi <goffi@goffi.org>
parents: 3747
diff changeset
779 def _date_fmt(
73936abc6838 tools (common/template): let specify timezone name in `date_fmt` filter
Goffi <goffi@goffi.org>
parents: 3747
diff changeset
780 self,
73936abc6838 tools (common/template): let specify timezone name in `date_fmt` filter
Goffi <goffi@goffi.org>
parents: 3747
diff changeset
781 timestamp: Union[int, float],
73936abc6838 tools (common/template): let specify timezone name in `date_fmt` filter
Goffi <goffi@goffi.org>
parents: 3747
diff changeset
782 fmt: str = "short",
73936abc6838 tools (common/template): let specify timezone name in `date_fmt` filter
Goffi <goffi@goffi.org>
parents: 3747
diff changeset
783 date_only: bool = False,
73936abc6838 tools (common/template): let specify timezone name in `date_fmt` filter
Goffi <goffi@goffi.org>
parents: 3747
diff changeset
784 auto_limit: int = 7,
73936abc6838 tools (common/template): let specify timezone name in `date_fmt` filter
Goffi <goffi@goffi.org>
parents: 3747
diff changeset
785 auto_old_fmt: str = "short",
73936abc6838 tools (common/template): let specify timezone name in `date_fmt` filter
Goffi <goffi@goffi.org>
parents: 3747
diff changeset
786 auto_new_fmt: str = "relative",
73936abc6838 tools (common/template): let specify timezone name in `date_fmt` filter
Goffi <goffi@goffi.org>
parents: 3747
diff changeset
787 tz_name: Optional[str] = None
73936abc6838 tools (common/template): let specify timezone name in `date_fmt` filter
Goffi <goffi@goffi.org>
parents: 3747
diff changeset
788 ) -> str:
2599
5b26033c49a8 tools (common): moved date_fmt function from template filters to new date_utils module, so it can be used everywhere.
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
789 if is_undefined(fmt):
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
790 fmt = "short"
4031
a2d4bd1943ba tools (common/template): add 2 new filters: `timestamp_to_hour` and `delta_to_human`:
Goffi <goffi@goffi.org>
parents: 4030
diff changeset
791
2453
84e84a46b014 template (filters): don't crash on invalid date in date_fmt
Goffi <goffi@goffi.org>
parents: 2452
diff changeset
792 try:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
793 return date_utils.date_fmt(
2907
8ca12f30f61f template (filters): set locale when using "date_fmt"
Goffi <goffi@goffi.org>
parents: 2906
diff changeset
794 timestamp, fmt, date_only, auto_limit, auto_old_fmt,
4030
73936abc6838 tools (common/template): let specify timezone name in `date_fmt` filter
Goffi <goffi@goffi.org>
parents: 3747
diff changeset
795 auto_new_fmt, locale_str = self._locale_str,
73936abc6838 tools (common/template): let specify timezone name in `date_fmt` filter
Goffi <goffi@goffi.org>
parents: 3747
diff changeset
796 tz_info=tz_name or date_utils.TZ_UTC
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
797 )
2453
84e84a46b014 template (filters): don't crash on invalid date in date_fmt
Goffi <goffi@goffi.org>
parents: 2452
diff changeset
798 except Exception as e:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
799 log.warning(_("Can't parse date: {msg}").format(msg=e))
4031
a2d4bd1943ba tools (common/template): add 2 new filters: `timestamp_to_hour` and `delta_to_human`:
Goffi <goffi@goffi.org>
parents: 4030
diff changeset
800 return str(timestamp)
a2d4bd1943ba tools (common/template): add 2 new filters: `timestamp_to_hour` and `delta_to_human`:
Goffi <goffi@goffi.org>
parents: 4030
diff changeset
801
a2d4bd1943ba tools (common/template): add 2 new filters: `timestamp_to_hour` and `delta_to_human`:
Goffi <goffi@goffi.org>
parents: 4030
diff changeset
802 def _timestamp_to_hour(self, timestamp: float) -> int:
a2d4bd1943ba tools (common/template): add 2 new filters: `timestamp_to_hour` and `delta_to_human`:
Goffi <goffi@goffi.org>
parents: 4030
diff changeset
803 """Get hour of day corresponding to a timestamp"""
a2d4bd1943ba tools (common/template): add 2 new filters: `timestamp_to_hour` and `delta_to_human`:
Goffi <goffi@goffi.org>
parents: 4030
diff changeset
804 dt = datetime.fromtimestamp(timestamp)
a2d4bd1943ba tools (common/template): add 2 new filters: `timestamp_to_hour` and `delta_to_human`:
Goffi <goffi@goffi.org>
parents: 4030
diff changeset
805 return dt.hour
2453
84e84a46b014 template (filters): don't crash on invalid date in date_fmt
Goffi <goffi@goffi.org>
parents: 2452
diff changeset
806
2384
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
807 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
808 """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
809
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
810 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
811 """
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
812 return RE_ATTR_ESCAPE.sub("_", 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
813
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
814 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
815 """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
816
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
817 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
818 @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
819 @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
820 @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
821 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
822 """
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
823 classes = []
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
824 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
825 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
826 try:
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
827 for value in xmlui_item.widgets[name].values:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
828 classes.append(escaped_name + "_" + self.attr_escape(value))
2384
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
829 except KeyError:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
830 log.debug(
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
831 _('ignoring field "{name}": it doesn\'t exists').format(name=name)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
832 )
2384
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
833 continue
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
834 return " ".join(classes) or None
2384
d14c1a3e3244 template: new "xmlui_class" filter compute class names from name/values of requested fields.
Goffi <goffi@goffi.org>
parents: 2323
diff changeset
835
4081
84f6bee6440d installation: moved from `setup.py` to `pyproject.toml`:
Goffi <goffi@goffi.org>
parents: 4075
diff changeset
836 @pass_context
2422
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
837 def _item_filter(self, ctx, item, filters):
2402
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
838 """return item's value, filtered if suitable
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
839
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
840 @param item(object): item to filter
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
841 value must have name and value attributes,
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
842 mostly used for XMLUI items
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
843 @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
844 if filter is None, return the value unchanged
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
845 if filter is a callable, apply it
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
846 if filter is a dict, it can have following keys:
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
847 - filters: iterable of filters to apply
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
848 - filters_args: kwargs of filters in the same order as filters (use empty
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
849 dict if needed)
2402
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
850 - template: template to format where {value} is the filtered value
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
851 """
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
852 value = item.value
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
853 filter_ = filters.get(item.name, None)
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
854 if filter_ is None:
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
855 return value
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
856 elif isinstance(filter_, dict):
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
857 filters_args = filter_.get("filters_args")
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
858 for idx, f_name in enumerate(filter_.get("filters", [])):
2422
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
859 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
860 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
861 try:
4081
84f6bee6440d installation: moved from `setup.py` to `pyproject.toml`:
Goffi <goffi@goffi.org>
parents: 4075
diff changeset
862 eval_context_filter = filter_func.evalpass_context
2422
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
863 except AttributeError:
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
864 eval_context_filter = False
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
865
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
866 if eval_context_filter:
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
867 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
868 else:
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
869 value = filter_func(value, **kwargs)
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
870 template = filter_.get("template")
2422
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
871 if template:
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
872 # 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
873 # 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
874 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
875 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
876 if is_safe:
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
877 value = safe(value)
5425cf18929b template: fixed the use of eval_context_filter in item_filter
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
878 return value
2402
f905dfe69fcc template: new item_value filter
Goffi <goffi@goffi.org>
parents: 2401
diff changeset
879
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
880 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
881 """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
882
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
883 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
884 @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
885 @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
886 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
887 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
888 @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
889 """
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
890 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
891 return value
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
892 #  jinja use string when no special char is used, so we have to convert to unicode
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
893 return str(template).format(value=value, **kwargs)
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
894
2425
d294527bd46f template: added dict_ext filter to extend a dictionary
Goffi <goffi@goffi.org>
parents: 2422
diff changeset
895 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
896 """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
897
d294527bd46f template: added dict_ext filter to extend a dictionary
Goffi <goffi@goffi.org>
parents: 2422
diff changeset
898 @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
899 @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
900 None to return source_dict unmodified
d294527bd46f template: added dict_ext filter to extend a dictionary
Goffi <goffi@goffi.org>
parents: 2422
diff changeset
901 @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
902 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
903 @return (dict): resulting dictionary
d294527bd46f template: added dict_ext filter to extend a dictionary
Goffi <goffi@goffi.org>
parents: 2422
diff changeset
904 """
d294527bd46f template: added dict_ext filter to extend a dictionary
Goffi <goffi@goffi.org>
parents: 2422
diff changeset
905 if extra_dict is None:
d294527bd46f template: added dict_ext filter to extend a dictionary
Goffi <goffi@goffi.org>
parents: 2422
diff changeset
906 return source_dict
d294527bd46f template: added dict_ext filter to extend a dictionary
Goffi <goffi@goffi.org>
parents: 2422
diff changeset
907 if key is not None:
d294527bd46f template: added dict_ext filter to extend a dictionary
Goffi <goffi@goffi.org>
parents: 2422
diff changeset
908 extra_dict = extra_dict.get(key, {})
d294527bd46f template: added dict_ext filter to extend a dictionary
Goffi <goffi@goffi.org>
parents: 2422
diff changeset
909 ret = source_dict.copy()
d294527bd46f template: added dict_ext filter to extend a dictionary
Goffi <goffi@goffi.org>
parents: 2422
diff changeset
910 ret.update(extra_dict)
d294527bd46f template: added dict_ext filter to extend a dictionary
Goffi <goffi@goffi.org>
parents: 2422
diff changeset
911 return ret
d294527bd46f template: added dict_ext filter to extend a dictionary
Goffi <goffi@goffi.org>
parents: 2422
diff changeset
912
2454
06ff33052354 core, template (filters): added pygments as a dependency + new highlight filter to use it.
Goffi <goffi@goffi.org>
parents: 2453
diff changeset
913 def highlight(self, code, lexer_name=None, lexer_opts=None, html_fmt_opts=None):
06ff33052354 core, template (filters): added pygments as a dependency + new highlight filter to use it.
Goffi <goffi@goffi.org>
parents: 2453
diff changeset
914 """Do syntax highlighting on code
06ff33052354 core, template (filters): added pygments as a dependency + new highlight filter to use it.
Goffi <goffi@goffi.org>
parents: 2453
diff changeset
915
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
916 Under the hood, pygments is used, check its documentation for options possible
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
917 values.
2454
06ff33052354 core, template (filters): added pygments as a dependency + new highlight filter to use it.
Goffi <goffi@goffi.org>
parents: 2453
diff changeset
918 @param code(unicode): code or markup to highlight
06ff33052354 core, template (filters): added pygments as a dependency + new highlight filter to use it.
Goffi <goffi@goffi.org>
parents: 2453
diff changeset
919 @param lexer_name(unicode, None): name of the lexer to use
06ff33052354 core, template (filters): added pygments as a dependency + new highlight filter to use it.
Goffi <goffi@goffi.org>
parents: 2453
diff changeset
920 None to autodetect it
06ff33052354 core, template (filters): added pygments as a dependency + new highlight filter to use it.
Goffi <goffi@goffi.org>
parents: 2453
diff changeset
921 @param html_fmt_opts(dict, None): kword arguments to use for HtmlFormatter
06ff33052354 core, template (filters): added pygments as a dependency + new highlight filter to use it.
Goffi <goffi@goffi.org>
parents: 2453
diff changeset
922 @return (unicode): HTML markup with highlight classes
06ff33052354 core, template (filters): added pygments as a dependency + new highlight filter to use it.
Goffi <goffi@goffi.org>
parents: 2453
diff changeset
923 """
06ff33052354 core, template (filters): added pygments as a dependency + new highlight filter to use it.
Goffi <goffi@goffi.org>
parents: 2453
diff changeset
924 if lexer_opts is None:
06ff33052354 core, template (filters): added pygments as a dependency + new highlight filter to use it.
Goffi <goffi@goffi.org>
parents: 2453
diff changeset
925 lexer_opts = {}
06ff33052354 core, template (filters): added pygments as a dependency + new highlight filter to use it.
Goffi <goffi@goffi.org>
parents: 2453
diff changeset
926 if html_fmt_opts is None:
06ff33052354 core, template (filters): added pygments as a dependency + new highlight filter to use it.
Goffi <goffi@goffi.org>
parents: 2453
diff changeset
927 html_fmt_opts = {}
06ff33052354 core, template (filters): added pygments as a dependency + new highlight filter to use it.
Goffi <goffi@goffi.org>
parents: 2453
diff changeset
928 if lexer_name is None:
06ff33052354 core, template (filters): added pygments as a dependency + new highlight filter to use it.
Goffi <goffi@goffi.org>
parents: 2453
diff changeset
929 lexer = lexers.guess_lexer(code, **lexer_opts)
06ff33052354 core, template (filters): added pygments as a dependency + new highlight filter to use it.
Goffi <goffi@goffi.org>
parents: 2453
diff changeset
930 else:
06ff33052354 core, template (filters): added pygments as a dependency + new highlight filter to use it.
Goffi <goffi@goffi.org>
parents: 2453
diff changeset
931 lexer = lexers.get_lexer_by_name(lexer_name, **lexer_opts)
06ff33052354 core, template (filters): added pygments as a dependency + new highlight filter to use it.
Goffi <goffi@goffi.org>
parents: 2453
diff changeset
932 formatter = formatters.HtmlFormatter(**html_fmt_opts)
06ff33052354 core, template (filters): added pygments as a dependency + new highlight filter to use it.
Goffi <goffi@goffi.org>
parents: 2453
diff changeset
933 return safe(pygments.highlight(code, lexer, formatter))
06ff33052354 core, template (filters): added pygments as a dependency + new highlight filter to use it.
Goffi <goffi@goffi.org>
parents: 2453
diff changeset
934
4100
810921c33a47 tools (common/template): add filter to get media types:
Goffi <goffi@goffi.org>
parents: 4089
diff changeset
935 def media_type_main(self, value: Optional[str]) -> Optional[str]:
810921c33a47 tools (common/template): add filter to get media types:
Goffi <goffi@goffi.org>
parents: 4089
diff changeset
936 """Return main type of a media type"""
810921c33a47 tools (common/template): add filter to get media types:
Goffi <goffi@goffi.org>
parents: 4089
diff changeset
937 if not value:
810921c33a47 tools (common/template): add filter to get media types:
Goffi <goffi@goffi.org>
parents: 4089
diff changeset
938 return None
810921c33a47 tools (common/template): add filter to get media types:
Goffi <goffi@goffi.org>
parents: 4089
diff changeset
939 return value.partition("/")[0]
810921c33a47 tools (common/template): add filter to get media types:
Goffi <goffi@goffi.org>
parents: 4089
diff changeset
940
810921c33a47 tools (common/template): add filter to get media types:
Goffi <goffi@goffi.org>
parents: 4089
diff changeset
941 def media_type_sub(self, value: Optional[str]) -> Optional[str]:
810921c33a47 tools (common/template): add filter to get media types:
Goffi <goffi@goffi.org>
parents: 4089
diff changeset
942 """Return main type of a media type"""
810921c33a47 tools (common/template): add filter to get media types:
Goffi <goffi@goffi.org>
parents: 4089
diff changeset
943 if not value:
810921c33a47 tools (common/template): add filter to get media types:
Goffi <goffi@goffi.org>
parents: 4089
diff changeset
944 return None
810921c33a47 tools (common/template): add filter to get media types:
Goffi <goffi@goffi.org>
parents: 4089
diff changeset
945 return value.partition("/")[1]
810921c33a47 tools (common/template): add filter to get media types:
Goffi <goffi@goffi.org>
parents: 4089
diff changeset
946
2403
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
947 ## custom tests ##
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
948
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
949 def _in_the_past(self, timestamp):
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
950 """check if a date is in the past
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
951
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
952 @param timestamp(unicode, int): unix time
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
953 @return (bool): True if date is in the past
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
954 """
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
955 return time.time() > int(timestamp)
dec31114c402 template: improved date formatter:
Goffi <goffi@goffi.org>
parents: 2402
diff changeset
956
2515
00480cf83fa1 template: added icon handling:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
957 ## template methods ##
00480cf83fa1 template: added icon handling:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
958
00480cf83fa1 template: added icon handling:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
959 def _icon_defs(self, *names):
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
960 """Define svg icons which will be used in the template.
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
961
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
962 Their name is used as id
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
963 """
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
964 svg_elt = etree.Element(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
965 "svg",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
966 nsmap={None: "http://www.w3.org/2000/svg"},
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
967 width="0",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
968 height="0",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
969 style="display: block",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
970 )
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
971 defs_elt = etree.SubElement(svg_elt, "defs")
2515
00480cf83fa1 template: added icon handling:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
972 for name in names:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
973 path = os.path.join(self.icons_path, name + ".svg")
2515
00480cf83fa1 template: added icon handling:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
974 icon_svg_elt = etree.parse(path).getroot()
00480cf83fa1 template: added icon handling:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
975 # we use icon name as id, so we can retrieve them easily
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
976 icon_svg_elt.set("id", name)
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
977 if not icon_svg_elt.tag == "{http://www.w3.org/2000/svg}svg":
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
978 raise exceptions.DataError("invalid SVG element")
2515
00480cf83fa1 template: added icon handling:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
979 defs_elt.append(icon_svg_elt)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
980 return safe(etree.tostring(svg_elt, encoding="unicode"))
2515
00480cf83fa1 template: added icon handling:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
981
4089
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
982 def _icon_use(self, name: str, cls: str = "", **kwargs: str) -> safe:
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
983 """Insert a icon previously defined with [_icon_defs]"""
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
984 extra_attrs = " ".join(f'{k}="{html.escape(str(v))}"' for k, v in kwargs.items())
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
985 return safe(
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
986 '<svg class="svg-icon{cls}"{extra_attrs} xmlns="http://www.w3.org/2000/svg" '
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
987 'viewBox="0 0 100 100">\n'
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
988 ' <use href="#{name}"/>'
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
989 '</svg>\n'.format(
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
990 name=name,
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
991 cls=(" " + cls) if cls else "",
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
992 extra_attrs=" " + extra_attrs if extra_attrs else ""
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
993 )
e7ee611fc860 tools (common/template): allow use of extra attributes in `icon` function
Goffi <goffi@goffi.org>
parents: 4084
diff changeset
994 )
2515
00480cf83fa1 template: added icon handling:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
995
3274
430204a3cc10 tools (common/template): new `icon_from_client` method:
Goffi <goffi@goffi.org>
parents: 3268
diff changeset
996 def _icon_from_client(self, client):
430204a3cc10 tools (common/template): new `icon_from_client` method:
Goffi <goffi@goffi.org>
parents: 3268
diff changeset
997 """Get icon name to represent a disco client"""
430204a3cc10 tools (common/template): new `icon_from_client` method:
Goffi <goffi@goffi.org>
parents: 3268
diff changeset
998 if client is None:
430204a3cc10 tools (common/template): new `icon_from_client` method:
Goffi <goffi@goffi.org>
parents: 3268
diff changeset
999 return 'desktop'
430204a3cc10 tools (common/template): new `icon_from_client` method:
Goffi <goffi@goffi.org>
parents: 3268
diff changeset
1000 elif 'pc' in client:
430204a3cc10 tools (common/template): new `icon_from_client` method:
Goffi <goffi@goffi.org>
parents: 3268
diff changeset
1001 return 'desktop'
430204a3cc10 tools (common/template): new `icon_from_client` method:
Goffi <goffi@goffi.org>
parents: 3268
diff changeset
1002 elif 'phone' in client:
430204a3cc10 tools (common/template): new `icon_from_client` method:
Goffi <goffi@goffi.org>
parents: 3268
diff changeset
1003 return 'mobile'
430204a3cc10 tools (common/template): new `icon_from_client` method:
Goffi <goffi@goffi.org>
parents: 3268
diff changeset
1004 elif 'web' in client:
430204a3cc10 tools (common/template): new `icon_from_client` method:
Goffi <goffi@goffi.org>
parents: 3268
diff changeset
1005 return 'globe'
430204a3cc10 tools (common/template): new `icon_from_client` method:
Goffi <goffi@goffi.org>
parents: 3268
diff changeset
1006 elif 'console' in client:
430204a3cc10 tools (common/template): new `icon_from_client` method:
Goffi <goffi@goffi.org>
parents: 3268
diff changeset
1007 return 'terminal'
430204a3cc10 tools (common/template): new `icon_from_client` method:
Goffi <goffi@goffi.org>
parents: 3268
diff changeset
1008 else:
430204a3cc10 tools (common/template): new `icon_from_client` method:
Goffi <goffi@goffi.org>
parents: 3268
diff changeset
1009 return 'desktop'
430204a3cc10 tools (common/template): new `icon_from_client` method:
Goffi <goffi@goffi.org>
parents: 3268
diff changeset
1010
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
1011 def render(self, template, site=None, theme=None, locale=C.DEFAULT_LOCALE,
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
1012 media_path="", css_files=None, css_inline=False, **kwargs):
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
1013 """Render a template
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
1014
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
1015 @param template(unicode): template to render (e.g. blog/articles.html)
3267
2eeca6fd08f7 tools (common/template): typos
Goffi <goffi@goffi.org>
parents: 3266
diff changeset
1016 @param site(unicode): site name
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
1017 None or empty string for defaut site (i.e. SàT templates)
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1018 @param theme(unicode): template theme
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
1019 @param media_path(unicode): prefix of the SàT media path/URL to use for
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
1020 template root. Must end with a u'/'
3267
2eeca6fd08f7 tools (common/template): typos
Goffi <goffi@goffi.org>
parents: 3266
diff changeset
1021 @param css_files(list[unicode],None): CSS files to use
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
1022 CSS files must be in static dir of the template
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
1023 use None for automatic selection of CSS files based on template category
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
1024 None is recommended. General static/style.css and theme file name will be
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
1025 used.
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1026 @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
1027 @param **kwargs: variable to transmit to the template
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1028 """
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
1029 if not template:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
1030 raise ValueError("template can't be empty")
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
1031 if site is not None or theme is not None:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
1032 # user wants to set site and/or theme, so we add it to the template path
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
1033 if site is None:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
1034 site = ''
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
1035 if theme is None:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
1036 theme = C.TEMPLATE_THEME_DEFAULT
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
1037 if template[0] == "(":
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
1038 raise ValueError(
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
1039 "you can't specify site or theme in template path and in argument "
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
1040 "at the same time"
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
1041 )
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
1042
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
1043 template_data = TemplateData(site, theme, template)
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
1044 template = "({site}/{theme}){template}".format(
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
1045 site=site, theme=theme, template=template)
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
1046 else:
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
1047 template_data = self.env.loader.parse_template(template)
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1048
2676
da8f3ac86845 template: overriden get_template to always have full template name:
Goffi <goffi@goffi.org>
parents: 2675
diff changeset
1049 # we need to save template_data in environment, to load right templates when they
da8f3ac86845 template: overriden get_template to always have full template name:
Goffi <goffi@goffi.org>
parents: 2675
diff changeset
1050 # are referenced from other templates (e.g. import)
da8f3ac86845 template: overriden get_template to always have full template name:
Goffi <goffi@goffi.org>
parents: 2675
diff changeset
1051 # FIXME: this trick will not work anymore if we use async templates (it works
da8f3ac86845 template: overriden get_template to always have full template name:
Goffi <goffi@goffi.org>
parents: 2675
diff changeset
1052 # here because we know that the rendering will be blocking until we unset
da8f3ac86845 template: overriden get_template to always have full template name:
Goffi <goffi@goffi.org>
parents: 2675
diff changeset
1053 # _template_data)
da8f3ac86845 template: overriden get_template to always have full template name:
Goffi <goffi@goffi.org>
parents: 2675
diff changeset
1054 self.env._template_data = template_data
da8f3ac86845 template: overriden get_template to always have full template name:
Goffi <goffi@goffi.org>
parents: 2675
diff changeset
1055
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
1056 template_source = self.env.get_template(template)
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
1057
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
1058 if css_files is None:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4031
diff changeset
1059 css_files, css_files_noscript = self.get_css_files(template_data)
3747
dd1d1a582438 tools (common/template): fix setting of `css_files_noscript` when `css_file` is specified
Goffi <goffi@goffi.org>
parents: 3479
diff changeset
1060 else:
dd1d1a582438 tools (common/template): fix setting of `css_files_noscript` when `css_file` is specified
Goffi <goffi@goffi.org>
parents: 3479
diff changeset
1061 css_files_noscript = []
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
1062
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
1063 kwargs["icon_defs"] = self._icon_defs
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
1064 kwargs["icon"] = self._icon_use
3274
430204a3cc10 tools (common/template): new `icon_from_client` method:
Goffi <goffi@goffi.org>
parents: 3268
diff changeset
1065 kwargs["icon_from_client"] = self._icon_from_client
2515
00480cf83fa1 template: added icon handling:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
1066
2159
5734b0994cf0 core (tools/common): template renderer first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1067 if css_inline:
2169
f472179305a1 tools(templates): workflow improvments:
Goffi <goffi@goffi.org>
parents: 2159
diff changeset
1068 css_contents = []
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
1069 for files, suffix in ((css_files, ""),
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
1070 (css_files_noscript, "_noscript")):
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
1071 site_root_dir = self.sites_paths[template_data.site]
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
1072 for css_file in files:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
1073 css_file_path = os.path.join(site_root_dir, css_file)
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
1074 with open(css_file_path) as f:
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
1075 css_contents.append(f.read())
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
1076 if css_contents:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2952
diff changeset
1077 kwargs["css_content" + suffix] = "\n".join(css_contents)
2245
e09048cb7595 core (tools/common/template): helping methods/filters for templates:
Goffi <goffi@goffi.org>
parents: 2169
diff changeset
1078
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
1079 scripts_handler = ScriptsHandler(self, template_data)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4031
diff changeset
1080 self.set_locale(locale)
2676
da8f3ac86845 template: overriden get_template to always have full template name:
Goffi <goffi@goffi.org>
parents: 2675
diff changeset
1081
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
1082 # XXX: theme used in template arguments is the requested theme, which may differ
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
1083 # from actual theme if the template doesn't exist in the requested theme.
2676
da8f3ac86845 template: overriden get_template to always have full template name:
Goffi <goffi@goffi.org>
parents: 2675
diff changeset
1084 rendered = template_source.render(
2671
0fa217fafabf tools (common/template), jp: refactoring to handle multiple sites:
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
1085 template_data=template_data,
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
1086 media_path=media_path,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
1087 css_files=css_files,
2680
ae5340b57ff8 template: fixed by variable used in css_files_noscript
Goffi <goffi@goffi.org>
parents: 2676
diff changeset
1088 css_files_noscript=css_files_noscript,
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
1089 locale=self._locale,
2903
68a7543ebbb3 template: added "locales" variables to templates:
Goffi <goffi@goffi.org>
parents: 2877
diff changeset
1090 locales=self.locales,
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
1091 gidx=Indexer(),
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
1092 script=scripts_handler,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
1093 **kwargs
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2599
diff changeset
1094 )
2676
da8f3ac86845 template: overriden get_template to always have full template name:
Goffi <goffi@goffi.org>
parents: 2675
diff changeset
1095 self.env._template_data = None
da8f3ac86845 template: overriden get_template to always have full template name:
Goffi <goffi@goffi.org>
parents: 2675
diff changeset
1096 return rendered