annotate libervia/backend/tools/common/template.py @ 4219:1b5cf2ee1d86

plugin XEP-0384, XEP-0391: download missing devices list: when a peer jid was not in our roster, devices list was not retrieved, resulting in failed en/decryption. This patch does check it and download missing devices list in necessary. There is no subscription managed yet, so the list won't be updated in case of new devices, this should be addressed at some point.
author Goffi <goffi@goffi.org>
date Tue, 05 Mar 2024 17:31:36 +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