From fd0fb390ffee0066a2864282f52b726c8b94cb69 Mon Sep 17 00:00:00 2001 From: "Brian S. Stephan" Date: Sat, 31 Dec 2022 09:35:51 -0600 Subject: [PATCH] allow for overriding PAGE_STYLES moving this allows for per-instance customizations later, but that won't be practical until serving styles from the instance dir is also allowed. but, this sets the ground work and does allow for removing some styles (e.g. if someone wanted to only allow 'plain'). also I still need to add the ability to present the themes list dynamically --- incorporealcms/config.py | 6 ++++++ incorporealcms/lib.py | 9 ++------- tests/test_pages.py | 28 ++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/incorporealcms/config.py b/incorporealcms/config.py index 5ed4258..f5bd28a 100644 --- a/incorporealcms/config.py +++ b/incorporealcms/config.py @@ -50,6 +50,12 @@ class Config(object): MEDIA_DIR = 'media' # customizations + PAGE_STYLES = { + 'dark': 'css/dark.css', + 'light': 'css/light.css', + 'plain': 'css/plain.css', + } + DEFAULT_PAGE_STYLE = 'light' TITLE_SUFFIX = 'example.com' CONTACT_EMAIL = 'admin@example.com' diff --git a/incorporealcms/lib.py b/incorporealcms/lib.py index 5973e1f..6bf8cd8 100644 --- a/incorporealcms/lib.py +++ b/incorporealcms/lib.py @@ -31,19 +31,14 @@ def render(template_name_or_list, **context): * Determine the proper site theme to use in the template and provide it. """ - PAGE_STYLES = { - 'dark': 'css/dark.css', - 'light': 'css/light.css', - 'plain': 'css/plain.css', - } - + page_styles = app.config['PAGE_STYLES'] selected_style = request.args.get('style', None) if selected_style: user_style = selected_style else: user_style = request.cookies.get('user-style') logger.debug("user style cookie: %s", user_style) - context['user_style'] = PAGE_STYLES.get(user_style, PAGE_STYLES.get(app.config['DEFAULT_PAGE_STYLE'])) + context['user_style'] = page_styles.get(user_style, page_styles.get(app.config['DEFAULT_PAGE_STYLE'])) resp = make_response(render_template(template_name_or_list, **context)) if selected_style: diff --git a/tests/test_pages.py b/tests/test_pages.py index 244abe0..9a1b0e6 100644 --- a/tests/test_pages.py +++ b/tests/test_pages.py @@ -1,10 +1,15 @@ """Unit test helper methods.""" +import os + import pytest from werkzeug.http import dump_cookie +from incorporealcms import create_app from incorporealcms.pages import (generate_parent_navs, instance_resource_path_to_request_path, render, request_path_to_breadcrumb_display, request_path_to_instance_resource_path) +HERE = os.path.dirname(os.path.abspath(__file__)) + def test_generate_page_navs_index(app): """Test that the index page has navs to the root (itself).""" @@ -67,6 +72,29 @@ def test_render_with_no_user_theme(app): assert b'/static/css/dark.css' not in render('base.html').data +def test_render_with_theme_overrides(app): + """Test that the loaded themes can be overridden from the default.""" + cookie = dump_cookie("user-style", 'cool') + restyled_app = create_app(instance_path=os.path.join(HERE, 'instance'), + test_config={'PAGE_STYLES': {'cool': 'css/cool.css', + 'warm': 'css/warm.css'}}) + with restyled_app.test_request_context(headers={'COOKIE': cookie}): + assert b'/static/css/cool.css' in render('base.html').data + assert b'/static/css/warm.css' not in render('base.html').data + + +def test_render_with_theme_overrides_not_found_is_default(app): + """Test that theme overrides work, and if a requested theme doesn't exist, the default is loaded.""" + cookie = dump_cookie("user-style", 'nonexistent') + restyled_app = create_app(instance_path=os.path.join(HERE, 'instance'), + test_config={'PAGE_STYLES': {'cool': 'css/cool.css', + 'warm': 'css/warm.css'}, + 'DEFAULT_PAGE_STYLE': 'warm'}) + with restyled_app.test_request_context(headers={'COOKIE': cookie}): + assert b'/static/css/warm.css' in render('base.html').data + assert b'/static/css/nonexistent.css' not in render('base.html').data + + def test_request_path_to_instance_resource_path(app): """Test a normal URL request is transformed into the file path.""" with app.test_request_context():