diff --git a/invenio_pages/ext.py b/invenio_pages/ext.py index e2fa241..f67ce33 100644 --- a/invenio_pages/ext.py +++ b/invenio_pages/ext.py @@ -2,20 +2,22 @@ # # This file is part of Invenio. # Copyright (C) 2015-2022 CERN. +# Copyright (C) 2023 Graz University of Technology. # # 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. """Static pages module for Invenio.""" -from flask import url_for +from flask import request, url_for from jinja2.sandbox import SandboxedEnvironment from werkzeug.exceptions import NotFound from . import config +from .records.models import PageModel as Page from .resources import PageResource, PageResourceConfig from .services import PageService, PageServiceConfig -from .views import handle_not_found +from .views import add_url_rule, handle_not_found, render_page class InvenioPages(object): @@ -113,3 +115,29 @@ def init_resources(self, app): class InvenioPagesREST(InvenioPages): """Invenio App ILS REST API app.""" + + +def finalize_app(app): + """Finalize app.""" + register_pages(app) + + +def register_pages(app): + """Register URL rule of all static pages to the application.""" + # We need to set the function view, to be able to directly register the urls + # in the Flask.url_map + app.view_functions["invenio_pages.view"] = view + + for page in Page.query.all(): + add_url_rule(page.url) + + +def view(): + """Public interface to the page view. + + Models: `pages.pages`. + Templates: Uses the template defined by the ``template_name`` field + or ``pages/default.html`` if template_name is not defined. + Context: page `pages.pages` object. + """ + return render_page(request.path) # pragma: no cover diff --git a/invenio_pages/views.py b/invenio_pages/views.py index 4627769..d7fabc1 100644 --- a/invenio_pages/views.py +++ b/invenio_pages/views.py @@ -2,6 +2,7 @@ # # This file is part of Invenio. # Copyright (C) 2015-2022 CERN. +# Copyright (C) 2023 Graz University of Technology. # # 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,8 +15,7 @@ from sqlalchemy.orm.exc import NoResultFound from werkzeug.exceptions import NotFound -from invenio_pages.proxies import current_pages_service - +from .proxies import current_pages_service from .records.models import PageModel as Page blueprint = Blueprint( @@ -23,16 +23,6 @@ ) -@blueprint.before_app_first_request -def register_pages(): - """Register URL rule of all static pages to the application.""" - # We need to set the function view, to be able to directly register the urls in the Flask.url_map - current_app.view_functions["invenio_pages.view"] = view - - for page in Page.query.all(): - _add_url_rule(page.url) - - @blueprint.app_template_filter("render_string") def render_string(source): """Render a string in sandboxed environment. @@ -43,32 +33,6 @@ def render_string(source): return current_app.extensions["invenio-pages"].render_template(source) -def view(): - """Public interface to the page view. - - Models: `pages.pages`. - Templates: Uses the template defined by the ``template_name`` field - or ``pages/default.html`` if template_name is not defined. - Context: page `pages.pages` object. - """ - return render_page(request.path) # pragma: no cover - - -def render_page(path): - """Internal interface to the page view. - - :param path: Page path. - :returns: The rendered template. - """ - try: - page = current_pages_service.read_by_url(g.identity, request.path).to_dict() - except NoResultFound: - abort(404) - return render_template( - [page["template_name"], current_app.config["PAGES_DEFAULT_TEMPLATE"]], page=page - ) - - def handle_not_found(exception, **extra): """Custom blueprint exception handler.""" assert isinstance(exception, NotFound) @@ -77,7 +41,7 @@ def handle_not_found(exception, **extra): db.or_(Page.url == request.path, Page.url == request.path + "/") ).first() if page: - _add_url_rule(page.url) + add_url_rule(page.url) return render_template( [page.template_name, current_app.config["PAGES_DEFAULT_TEMPLATE"]], page=page, @@ -88,7 +52,7 @@ def handle_not_found(exception, **extra): return exception -def _add_url_rule(url): +def add_url_rule(url, app=None): """Register URL rule to application URL map.""" rule = current_app.url_rule_class( url, @@ -104,3 +68,18 @@ def create_pages_api_bp(app): """Create the pages resource api blueprint.""" ext = app.extensions["invenio-pages"] return ext.pages_resource.as_blueprint() + + +def render_page(path): + """Internal interface to the page view. + + :param path: Page path. + :returns: The rendered template. + """ + try: + page = current_pages_service.read_by_url(g.identity, request.path).to_dict() + except NoResultFound: + abort(404) + return render_template( + [page["template_name"], current_app.config["PAGES_DEFAULT_TEMPLATE"]], page=page + ) diff --git a/setup.cfg b/setup.cfg index 44f4e86..5215399 100644 --- a/setup.cfg +++ b/setup.cfg @@ -74,6 +74,8 @@ invenio_administration.views = invenio_pages_list = invenio_pages.administration.views.pages:PageListView invenio_pages_details = invenio_pages.administration.views.pages:PageDetailView invenio_pages_create = invenio_pages.administration.views.pages:PageEditView +invenio_base.finalize_app = + invenio_pages = invenio_pages.ext:finalize_app [extract_messages] copyright_holder = CERN