Jinja2
Jinja2 is a fast, expressive, extensible templating engine for Python. Special placeholders in templates allow writing code similar to Python syntax, which is then rendered against passed data to produce a final document. It supports template inheritance, macros, autoescaping, sandboxed execution, async rendering, and i18n via Babel. Current stable version is 3.1.6 (a security patch release); the 3.1.x branch receives active bugfix and security updates with no fixed cadence.
Warnings
- breaking jinja2.Markup and jinja2.escape were removed in 3.1.0. Any code doing `from jinja2 import Markup` or `from jinja2 import escape` raises ImportError.
- breaking contextfunction, contextfilter, environmentfunction, environmentfilter, evalcontextfunction, and evalcontextfilter decorators were removed in 3.0. Importing them raises ImportError.
- breaking Python 2.7 and 3.5 support was dropped in 3.0; Python 3.6 support was dropped in 3.1.0. Running on these versions will fail.
- gotcha autoescape defaults to False in Environment. Rendering HTML with user input without enabling autoescape exposes the app to XSS attacks. Bandit (B701) and CodeQL flag this as high severity.
- gotcha Wrapping user-supplied strings in Markup() bypasses autoescaping entirely and causes XSS. Markup() signals a string is already safe; passing untrusted input to it is a common mistake.
- gotcha Server-Side Template Injection (SSTI): passing user-controlled strings as the template source (e.g. env.from_string(user_input) or render_template_string(request.args['tmpl'])) allows arbitrary code execution.
- gotcha Macros imported from another file do not have access to the calling template's context variables by default. Accessing outer-scope variables inside imported macros silently returns Undefined.
Install
-
pip install Jinja2 -
pip install "Jinja2>=3.1.6"
Imports
- Environment
from jinja2 import Environment
- FileSystemLoader
from jinja2 import FileSystemLoader
- PackageLoader
from jinja2 import PackageLoader
- select_autoescape
from jinja2 import select_autoescape
- Markup
from markupsafe import Markup
- escape
from markupsafe import escape
- pass_context / pass_environment / pass_eval_context
from jinja2 import pass_context
- SandboxedEnvironment
from jinja2.sandbox import SandboxedEnvironment
- UndefinedError
from jinja2 import UndefinedError
Quickstart
from jinja2 import Environment, FileSystemLoader, select_autoescape
# Always set autoescape explicitly; default is False which is a security risk for HTML output
env = Environment(
loader=FileSystemLoader("."),
autoescape=select_autoescape(["html", "htm", "xml"]),
)
# Render from a string (autoescape=False for non-HTML plain text)
text_env = Environment()
template = text_env.from_string("Hello, {{ name }}! You have {{ count }} message(s).")
result = template.render(name="World", count=3)
print(result)
# -> Hello, World! You have 3 message(s).
# Render an HTML template string safely
html_env = Environment(autoescape=True)
html_tmpl = html_env.from_string("<p>Hello, {{ name }}!</p>")
print(html_tmpl.render(name="<script>alert(1)</script>"))
# -> <p>Hello, <script>alert(1)</script>!</p>