Source code for flask_appfactory.ext.jinja2

# -*- coding: utf-8 -*-
#
# This file is part of Flask-AppFactory
# Copyright (C) 2015 CERN.
#
# Flask-AppFactory is free software; you can redistribute it and/or
# modify it under the terms of the Revised BSD License; see LICENSE
# file for more details.

"""Order-aware Jinja2 loader and extensions initialization.

The default Flask Jinja2 loader is not aware of the order defined in
``PACKAGES``. This means that if two modules provides the same template, it is
undefined which template is being rendered. This extension adds a
``PACKAGES`` order-aware Jinja2 loader, which will search for a given template
in each module in the order defined by ``PACKAGES``. This allows modules to
override templates defined in modules later in ``PACKAGES``.


Additionally the extension will load any Jinja2 extension defined in the
``JINJA2_EXTENSIONS`` configuration variable.
"""

from __future__ import absolute_import, print_function, unicode_literals

from distutils.version import LooseVersion
from flask import __version__ as flask_version
from flask.templating import DispatchingJinjaLoader
from jinja2 import ChoiceLoader

# Flask 1.0 changes return value of _iter_loaders so for compatibility with
# both Flask 0.10 and 1.0 we here check the version.
# See Flask commit bafc13981002dee4610234c7c97ac176766181c1
IS_FLASK_1_0 = LooseVersion(flask_version) >= LooseVersion("0.11-dev")

try:
    # Deprecated in Flask commit 817b72d484d353800d907b3580c899314bf7f3c6
    from flask.templating import blueprint_is_module
except ImportError:  # pragma: no cover
    def blueprint_is_module(blueprint):
        """Dummy function for Flask 1.0."""
        return False


[docs]class OrderAwareDispatchingJinjaLoader(DispatchingJinjaLoader): """Order aware dispatching Jinja loader. Customization of default Flask Jinja2 template loader. By default the Flask Jinja2 template loader is not aware of the order of Blueprints as defined by the ``PACKAGES`` configuration variable. """ def _iter_loaders(self, template): for blueprint in self.app.extensions['registry']['blueprints']: if blueprint_is_module(blueprint): continue # pragma: no cover loader = blueprint.jinja_loader if loader is not None: if IS_FLASK_1_0: yield blueprint, loader # pragma: no cover else: yield loader, template
[docs]def setup_app(app): """Initialize Jinja2 loader and extensions.""" # Customize Jinja loader. jinja_loader = ChoiceLoader([ OrderAwareDispatchingJinjaLoader(app), app.jinja_loader, ]) app.jinja_loader = jinja_loader # Load Jinja extensions for ext in app.config.get('JINJA2_EXTENSIONS', []): app.jinja_env.add_extension(ext)