Skip to main content

Jinja Environment and Templates

The application integrates the Jinja2 templating engine through the App and Scaffold classes. While Scaffold (defined in src/flask/sansio/scaffold.py) provides the foundational structure for template folders and context processors, the App class (defined in src/flask/sansio/app.py) manages the actual Jinja environment and provides the registration interface for filters, globals, and tests.

The Jinja Environment​

The central point of template management is the App.jinja_env property. This is a cached property that initializes the Jinja environment the first time it is accessed.

The environment is created via App.create_jinja_environment(). Developers can influence this environment in two primary ways:

  1. Configuration via jinja_options: This dictionary in the App class contains options passed directly to the Jinja environment constructor.
  2. Custom Environment Classes: By overriding the jinja_environment class attribute on a subclass of App, you can change the underlying environment implementation.
# Example of overriding the environment class (from tests/test_templating.py)
class CustomEnvironment(flask.templating.Environment):
pass

class CustomFlask(flask.Flask):
jinja_environment = CustomEnvironment

app = CustomFlask(__name__)

Note: Changing jinja_options after app.jinja_env has been accessed will have no effect because the environment is cached.

Extending Templates​

The App class provides several decorators and methods to extend Jinja's functionality. These must be called before the application handles its first request, enforced by the @setupmethod decorator.

Custom Filters​

Filters are used to transform data within templates. You can register them using the @app.template_filter() decorator or the add_template_filter() method.

# From src/flask/sansio/app.py
@app.template_filter("reverse")
def reverse_filter(s):
return reversed(s)

# Manual registration
def my_filter(s):
return s[::-1]
app.add_template_filter(my_filter, name="rev")

Globals and Tests​

Similar to filters, globals and tests can be registered to provide functions or boolean checks available in all templates.

  • Globals: Registered via @app.template_global() or add_template_global(). These are added to jinja_env.globals.
  • Tests: Registered via @app.template_test() or add_template_test(). These are added to jinja_env.tests.
@app.template_global
def double(n):
return 2 * n

@app.template_test("prime")
def is_prime_test(n):
# ... logic to check if n is prime ...
return True

Context Processors​

Context processors are managed by the Scaffold class and allow you to inject variables into the template context automatically. These functions run before a template is rendered and must return a dictionary.

The Scaffold.template_context_processors attribute stores these functions. By default, it includes a default processor that provides standard variables like config, request, session, and g.

# From src/flask/sansio/scaffold.py pattern
@app.context_processor
def inject_user():
return {"user": g.user}

When a template is rendered, the application merges the dictionaries returned by all registered context processors into the template's namespace.

Template Resolution and Loading​

Template loading is handled by a combination of the jinja_loader and the DispatchingJinjaLoader.

  1. Scaffold.template_folder: Both the application and blueprints can define a template_folder. This path is relative to the root_path of the object.
  2. Scaffold.jinja_loader: This property creates a jinja2.loaders.FileSystemLoader pointing to the configured template_folder.
  3. DispatchingJinjaLoader: The App class uses create_global_jinja_loader() to instantiate a DispatchingJinjaLoader. This loader coordinates template lookups by first checking the application's loader and then iterating through the loaders of all registered blueprints.

Configuration and Auto-Reloading​

The behavior of the Jinja environment is influenced by the application's configuration:

  • TEMPLATES_AUTO_RELOAD: If set to True, the environment will check for template source changes and reload them. If left as None, it automatically follows the DEBUG flag.
  • EXPLAIN_TEMPLATE_LOADING: When enabled, Flask logs the attempts made by the loader to find a template, which is useful for debugging TemplateNotFound errors.
  • Autoescaping: The App.select_jinja_autoescape() method determines if autoescaping is active based on the template filename. By default, it enables autoescaping for .html, .htm, .xml, .xhtml, and .svg files.
# How DEBUG influences auto_reload in App.debug setter
if self.config["TEMPLATES_AUTO_RELOAD"] is None:
self.jinja_env.auto_reload = value