Skip to main content

Templating & Rendering

Flask integrates the Jinja2 templating engine to provide a powerful system for generating dynamic HTML and other text formats. This integration includes custom template loaders that are aware of the application and its blueprints, as well as mechanisms for injecting global variables and custom filters.

Rendering Templates

The primary way to render templates is through the render_template function found in src/flask/templating.py. This function retrieves a template from the application's Jinja environment and renders it with the provided context.

from flask import render_template

@app.route("/")
def index():
return render_template("index.html", title="Home")

Flask provides several rendering variants:

  • render_template(template_name_or_list, **context): Renders a template file by name.
  • render_template_string(source, **context): Renders a template from a raw string.
  • stream_template(template_name_or_list, **context): Returns an iterator that yields the rendered template in chunks, which is useful for large responses. This is implemented using template.generate(context) and stream_with_context.

All rendering functions automatically trigger the before_render_template and template_rendered signals, as seen in the _render and _stream internal helpers in src/flask/templating.py.

Template Context

When a template is rendered, Flask automatically injects several variables into the context. This is managed by update_template_context in src/flask/app.py.

Standard Variables

The following variables are available in all templates by default:

  • config: The current application's configuration object.
  • request: The current request object.
  • session: The current session object.
  • g: The application context global variable.
  • url_for(): The helper function for generating URLs.
  • get_flashed_messages(): The function to retrieve messages flashed to the user.

Context Processors

You can inject additional variables into the template context using the @app.context_processor decorator. These functions must return a dictionary whose keys will be merged into the template context.

@app.context_processor
def inject_user():
return dict(user=g.user)

Flask includes a _default_template_ctx_processor in src/flask/templating.py that optimizes access by replacing the request and g proxies with their concrete objects when a request is active.

Customizing the Jinja Environment

The App class (and its base Scaffold) provides decorators to extend Jinja's functionality. These are implemented in src/flask/sansio/app.py.

Filters, Tests, and Globals

  • @app.template_filter(name=None): Registers a custom filter. For example, @app.template_filter("reverse") allows using {{ my_string|reverse }} in templates.
  • @app.template_test(name=None): Registers a custom test. For example, @app.template_test("prime") allows using {% if n is prime %}.
  • @app.template_global(name=None): Registers a function or variable as a global in the Jinja environment.

These decorators update the jinja_env.filters, jinja_env.tests, and jinja_env.globals dictionaries respectively.

Template Loading and Resolution

Flask uses a custom DispatchingJinjaLoader (defined in src/flask/templating.py) to locate templates. This loader is "blueprint-aware," meaning it searches for templates in a specific order:

  1. The application's own template_folder.
  2. The template_folder of each registered blueprint, in the order they were registered.

The jinja_loader property on Scaffold (the base for both Flask and Blueprint) returns a jinja2.FileSystemLoader if a template_folder was specified during initialization.

Debugging Template Resolution

If you are unsure why a specific template is being loaded (or why it cannot be found), you can set the EXPLAIN_TEMPLATE_LOADING configuration option to True. When enabled, Flask will log every attempt made by the DispatchingJinjaLoader to find a template, including which loaders were queried and whether they succeeded.

Advanced Features

Accessing Template Attributes

The get_template_attribute helper in src/flask/helpers.py allows you to load a macro or variable exported by a template directly into Python code.

from flask import get_template_attribute

hello_macro = get_template_attribute("_macros.html", "hello")
result = hello_macro("World")

Autoescaping

Autoescaping is enabled by default for files ending in .html, .htm, .xml, .xhtml, and .svg. This behavior is controlled by select_jinja_autoescape in src/flask/app.py, which checks the template name's extension.

Configuration Options

  • TEMPLATES_AUTO_RELOAD: If True, the Jinja environment will check for template source changes and reload them. If set to None (the default), it follows the application's debug flag.
  • EXPLAIN_TEMPLATE_LOADING: Enables detailed logging of the template resolution process.