Add theme support

This commit is contained in:
s3lph 2023-02-20 10:02:12 +01:00
parent c28f42a08d
commit c2de89201f
17 changed files with 86 additions and 7 deletions

View file

@ -93,6 +93,8 @@ build_debian:
- gzip -9n package/debian/matemat/usr/share/doc/matemat/changelog - gzip -9n package/debian/matemat/usr/share/doc/matemat/changelog
- cp -r static/ package/debian/matemat/usr/lib/matemat/static/ - cp -r static/ package/debian/matemat/usr/lib/matemat/static/
- cp -r templates/ package/debian/matemat/usr/lib/matemat/templates/ - cp -r templates/ package/debian/matemat/usr/lib/matemat/templates/
- mkdir -p package/debian/matemat/var/lib/matemat/
- cp -r themes/ package/debian/matemat/usr/lib/matemat/themes/
- python3.7 setup.py egg_info install --root=package/debian/matemat/ --prefix=/usr --optimize=1 - python3.7 setup.py egg_info install --root=package/debian/matemat/ --prefix=/usr --optimize=1
- cd package/debian - cd package/debian
- mkdir -p matemat/usr/lib/python3/dist-packages/ - mkdir -p matemat/usr/lib/python3/dist-packages/

View file

@ -1,5 +1,19 @@
# Matemat Changelog # Matemat Changelog
<!-- BEGIN RELEASE v0.3.0 -->
## Version 0.3.0
THEMES!
### Changes
<!-- BEGIN CHANGES 0.3.0 -->
- Add support for theming
- Themes can override both templates and static files
<!-- END CHANGES 0.3.0 -->
<!-- END RELEASE v0.3.0 -->
<!-- BEGIN RELEASE v0.2.14 --> <!-- BEGIN RELEASE v0.2.14 -->
## Version 0.2.14 ## Version 0.2.14

View file

@ -33,6 +33,7 @@ python -m matemat
- s3lph - s3lph
- SPiNNiX - SPiNNiX
- jonny
## License ## License

2
doc

@ -1 +1 @@
Subproject commit b49477b0c0f518ac6f3c1cfdc7c46c040a247366 Subproject commit 832ba0b4f363578653e6c2a04afedc65d90d979a

View file

@ -5,6 +5,8 @@ Port=80
StaticPath=/static StaticPath=/static
TemplatePath=/templates TemplatePath=/templates
ThemePath=/themes
Theme=base
LogTarget=stdout LogTarget=stdout

View file

@ -1,2 +1,2 @@
__version__ = '0.2.14' __version__ = '0.3.0'

View file

@ -1,3 +1,4 @@
import logging
from typing import Any, Dict, Iterable, Union from typing import Any, Dict, Iterable, Union
import sys import sys
@ -62,8 +63,12 @@ def _init(config: Dict[str, Any]):
@bottle.route('/static/<filename:path>') @bottle.route('/static/<filename:path>')
def serve_static_files(filename: str): def serve_static_files(filename: str):
config = get_config() config = get_config()
themeroot = os.path.abspath(os.path.join(config['themeroot'], config['theme'], 'static'))
staticroot = os.path.abspath(config['staticroot']) staticroot = os.path.abspath(config['staticroot'])
return bottle.static_file(filename, root=staticroot) resp = bottle.static_file(filename, root=themeroot)
if resp.status_code == 404:
resp = bottle.static_file(filename, root=staticroot)
return resp
def main(): def main():

View file

@ -68,6 +68,10 @@ def parse_config_file(paths: Union[str, Iterable[str]]) -> None:
config['staticroot'] = '/var/matemat/static' config['staticroot'] = '/var/matemat/static'
# Root directory of Jinja2 templates # Root directory of Jinja2 templates
config['templateroot'] = '/var/matemat/templates' config['templateroot'] = '/var/matemat/templates'
# Root directory of themes
config['themeroot'] = '/var/matemat/themes'
# Active theme - "base" is the default theme that does not override anything
config['theme'] = 'base'
# Log level # Log level
config['log_level'] = logging.INFO config['log_level'] = logging.INFO
# Log target: An IO stream (stderr, stdout, ...) or a filename # Log target: An IO stream (stderr, stdout, ...) or a filename
@ -104,6 +108,8 @@ def parse_config_file(paths: Union[str, Iterable[str]]) -> None:
parse_logging(parser['Matemat'].get('LogLevel', config['log_level']), parse_logging(parser['Matemat'].get('LogLevel', config['log_level']),
parser['Matemat'].get('LogTarget', 'stderr')) parser['Matemat'].get('LogTarget', 'stderr'))
config['templateroot'] = parser['Matemat'].get('TemplatePath', os.path.expanduser(config['templateroot'])) config['templateroot'] = parser['Matemat'].get('TemplatePath', os.path.expanduser(config['templateroot']))
config['themeroot'] = parser['Matemat'].get('ThemePath', os.path.expanduser(config['themeroot']))
config['theme'] = parser['Matemat'].get('Theme', config['theme'])
# Read all values from the [Pagelets] section, if present. These values are passed to pagelet functions # Read all values from the [Pagelets] section, if present. These values are passed to pagelet functions
if 'Pagelets' in parser.sections(): if 'Pagelets' in parser.sections():

View file

@ -11,8 +11,9 @@ __jinja_env: jinja2.Environment = None
def init(config: Dict[str, Any]) -> None: def init(config: Dict[str, Any]) -> None:
global __jinja_env global __jinja_env
themepath = os.path.abspath(os.path.join(config['themeroot'], config['theme'], 'templates'))
__jinja_env = jinja2.Environment( __jinja_env = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.abspath(config['templateroot'])), loader=jinja2.FileSystemLoader([themepath, os.path.abspath(config['templateroot'])]),
autoescape=jinja2.select_autoescape(default=True), autoescape=jinja2.select_autoescape(default=True),
) )
__jinja_env.filters['chf'] = format_chf __jinja_env.filters['chf'] = format_chf

View file

@ -5,6 +5,9 @@ Address=::
# The TCP port to listen on # The TCP port to listen on
Port=80 Port=80
# The theme to apply
#Theme=base
# The log level, one of NONE, DEBUG, INFO, WARNING, ERROR, CRITICAL # The log level, one of NONE, DEBUG, INFO, WARNING, ERROR, CRITICAL
LogLevel=DEBUG LogLevel=DEBUG

View file

@ -2,6 +2,7 @@
StaticPath=/usr/lib/matemat/static StaticPath=/usr/lib/matemat/static
TemplatePath=/usr/lib/matemat/templates TemplatePath=/usr/lib/matemat/templates
ThemePath=/var/lib/matemat/themes
LogTarget=stdout LogTarget=stdout

View file

@ -7,6 +7,10 @@
user-select: none; user-select: none;
} }
nav div {
display: inline-block;
}
.thumblist-item { .thumblist-item {
display: inline-block; display: inline-block;
margin: 5px; margin: 5px;

View file

@ -1,11 +1,12 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html lang="en">
<head> <head>
<meta name="viewport" content="width=device-width, initial-scale=1">
{% block head %} {% block head %}
{# Show the setup name, as set in the config file, as tab title. Don't escape HTML entities. #} {# Show the setup name, as set in the config file, as tab title. Don't escape HTML entities. #}
<title>{{ setupname|safe }}</title> <title>{{ setupname|safe }}</title>
<link rel="stylesheet" href="/static/css/matemat.css"/> <link rel="stylesheet" href="/static/css/matemat.css"/>
<link rel="stylesheet" href="/static/css/theme.css"/>
{% endblock %} {% endblock %}
</head> </head>
@ -15,7 +16,8 @@
{% block header %} {% block header %}
{# Always show a link to the home page, either a list of users or of products. #} {# Always show a link to the home page, either a list of users or of products. #}
<a href="/">Home</a> <nav class="navbarbutton">
<div class="selected"><a href="/">Home</a></div>
{# Show a link to the settings, if a user logged in via password (authlevel 2). #} {# Show a link to the settings, if a user logged in via password (authlevel 2). #}
{% if authlevel|default(0) > 1 %} {% if authlevel|default(0) > 1 %}
{% if authuser is defined %} {% if authuser is defined %}
@ -28,6 +30,7 @@
{% endif %} {% endif %}
{% endif %} {% endif %}
{% endif %} {% endif %}
</nav>
{% endblock %} {% endblock %}
</header> </header>

View file

View file

View file

@ -0,0 +1,37 @@
.thumblist-item:nth-child(6n+1) { background: #E40303; }
.thumblist-item:nth-child(6n+2) { background: #FF8C00; }
.thumblist-item:nth-child(6n+3) { background: #FFED00; }
.thumblist-item:nth-child(6n+4) { background: #008026; }
.thumblist-item:nth-child(6n+5) { background: #24408E; }
.thumblist-item:nth-child(6n+6) { background: #732982; }
footer li:nth-child(4n+1) { background: #000000; color: white; }
footer li:nth-child(4n+2) { background: #A3A3A3; }
footer li:nth-child(4n+3) { background: #FFFFFF; }
footer li:nth-child(4n+4) { background: #800080; color: white; }
.touchkey-svg-node:nth-child(16n+1) { fill: #D52D00; }
.touchkey-svg-node:nth-child(16n+5) { fill: #EF7627; }
.touchkey-svg-node:nth-child(16n+9) { fill: #FF9A56; }
.touchkey-svg-node:nth-child(16n+13) { fill: #FFFFFF; }
.touchkey-svg-node:nth-child(16n+14) { fill: #D162A4; }
.touchkey-svg-node:nth-child(16n+15) { fill: #B55690; }
.touchkey-svg-node:nth-child(16n+16) { fill: #A30262; }
.touchkey-svg-node:nth-child(16n+2) { fill: #5BCEFA; }
.touchkey-svg-node:nth-child(16n+6) { fill: #F5A9B8; }
.touchkey-svg-node:nth-child(16n+10) { fill: #FFFFFF; }
.touchkey-svg-node:nth-child(16n+11) { fill: #F5A9B8; }
.touchkey-svg-node:nth-child(16n+12) { fill: #5BCEFA; }
.touchkey-svg-node:nth-child(16n+3) { fill: #D60270; }
.touchkey-svg-node:nth-child(16n+7) { fill: #9B4F96; }
.touchkey-svg-node:nth-child(16n+8) { fill: #0038A8; }
.osk-kbd-row:nth-child(5n+1) .osk-button { background: #FFFFFF; }
.osk-kbd-row:nth-child(5n+2) .osk-button { background: #FFAFC8; }
.osk-kbd-row:nth-child(5n+3) .osk-button { background: #74D7EE; }
.osk-kbd-row:nth-child(5n+4) .osk-button { background: #613915; fill: white; }
.osk-kbd-row:nth-child(5n+5) .osk-button { background: #000000; fill: white; }

View file