diff --git a/invenio_theme/ext.py b/invenio_theme/ext.py index 7ee6896..a1f0407 100644 --- a/invenio_theme/ext.py +++ b/invenio_theme/ext.py @@ -3,6 +3,7 @@ # This file is part of Invenio. # Copyright (C) 2015-2018 CERN. # Copyright (C) 2022-2023 Graz University of Technology. +# Copyright (C) 2025 Northwestern University. # # Invenio is free software; you can redistribute it and/or modify it # under the terms of the MIT License; see LICENSE file for more details. @@ -14,6 +15,13 @@ from . import config from .icons import ThemeIcons +from .views import ( + insufficient_permissions, + internal_error, + page_not_found, + too_many_requests, + unauthorized, +) class InvenioTheme(object): @@ -76,3 +84,44 @@ def _generator_func_or_str(): def icons(self): """Return icons.""" return ThemeIcons(self.app.config["APP_THEME"], self.app.config["THEME_ICONS"]) + + +class InvenioApiTheme: + """Invenio theme extension for API app.""" + + def __init__(self, app=None): + r"""Extension initialization. + + :param app: An instance of :class:`~flask.Flask`. + """ + if app: + self.init_config(app) + + def init_config(self, app): + """Initialize configuration. + + :param app: An instance of :class:`~flask.Flask`. + """ + _vars = ["BASE_TEMPLATE", "COVER_TEMPLATE", "SETTINGS_TEMPLATE"] + + for k in dir(config): + if k.startswith("THEME_") or k in _vars: + app.config.setdefault(k, getattr(config, k)) + + # Set THEME__TEMPLATE from _TEMPLATE variables if not + # already set. + for varname in _vars: + theme_varname = f"THEME_{varname}" + if app.config[theme_varname] is None: + app.config[theme_varname] = app.config[varname] + + app.config.setdefault("ADMIN_BASE_TEMPLATE", config.ADMIN_BASE_TEMPLATE) + + +def finalize_app(app): + """Finalize app.""" + app.register_error_handler(401, unauthorized) + app.register_error_handler(403, insufficient_permissions) + app.register_error_handler(404, page_not_found) + app.register_error_handler(429, too_many_requests) + app.register_error_handler(500, internal_error) diff --git a/invenio_theme/views.py b/invenio_theme/views.py index ee7f64b..a75d74d 100644 --- a/invenio_theme/views.py +++ b/invenio_theme/views.py @@ -3,6 +3,7 @@ # This file is part of Invenio. # Copyright (C) 2015-2018 CERN. # Copyright (C) 2022-2023 Graz University of Technology. +# Copyright (C) 2025 Northwestern University. # # Invenio is free software; you can redistribute it and/or modify it # under the terms of the MIT License; see LICENSE file for more details. @@ -24,12 +25,6 @@ def create_blueprint(app): if app.config["THEME_FRONTPAGE"]: blueprint.add_url_rule("/", "index", view_func=index) - app.register_error_handler(401, unauthorized) - app.register_error_handler(403, insufficient_permissions) - app.register_error_handler(404, page_not_found) - app.register_error_handler(429, too_many_requests) - app.register_error_handler(500, internal_error) - return blueprint diff --git a/run-tests.sh b/run-tests.sh index 5702ade..06d8603 100755 --- a/run-tests.sh +++ b/run-tests.sh @@ -1,3 +1,4 @@ +#!/usr/bin/env sh # -*- coding: utf-8 -*- # # This file is part of Invenio. diff --git a/setup.cfg b/setup.cfg index f95e37a..17456d7 100644 --- a/setup.cfg +++ b/setup.cfg @@ -3,6 +3,7 @@ # This file is part of Invenio. # Copyright (C) 2015-2024 CERN. # Copyright (C) 2022-2024 Graz University of Technology. +# Copyright (C) 2025 Northwestern University. # # Invenio is free software; you can redistribute it and/or modify it # under the terms of the MIT License; see LICENSE file for more details. @@ -46,8 +47,12 @@ invenio_assets.webpack = invenio_theme = invenio_theme.webpack:theme invenio_base.apps = invenio_theme = invenio_theme:InvenioTheme +invenio_base.api_apps = + invenio_theme = invenio_theme:InvenioApiTheme invenio_base.blueprints = invenio_theme = invenio_theme.views:create_blueprint +invenio_base.finalize_app = + invenio_theme = invenio_theme.ext:finalize_app invenio_i18n.translations = messages = invenio_theme diff --git a/tests/conftest.py b/tests/conftest.py index 683de50..56abb60 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -27,6 +27,7 @@ from invenio_i18n.views import create_blueprint_from_app from invenio_theme import InvenioTheme +from invenio_theme.ext import finalize_app from invenio_theme.views import create_blueprint @@ -114,6 +115,7 @@ def tear_down(): InvenioTheme(app) app.register_blueprint(create_blueprint(app)) + finalize_app(app) return app