Every use of Jinja goes through an Environment, and its settings decide escaping, loading and errors.
A template is text with placeholders. The central object is the `Environment`: it holds configuration (autoescaping, undefined handling, filters, globals) and a loader that finds templates by name.
env = Environment(loader=FileSystemLoader("templates"), autoescape=select_autoescape())
template = env.get_template("hello.html")
html = template.render(name="Ann", items=[1, 2])render() takes keyword arguments or a single dict; the names become template variables, called the context. The result is a string. For huge outputs, template.generate() yields chunks and template.stream() can write to a file.
For quick scripts, Template("Hello {{ name }}!") or env.from_string(source) compiles a template from a string. Prefer one shared environment with a loader for real projects: it caches compiled templates and enables inheritance and imports between files.
An important default: a bare Environment() has autoescaping off. That is correct for plain text, YAML or SQL generation, but for HTML you must turn it on, usually with select_autoescape(), which enables it for .html, .htm and .xml templates. Frameworks such as Flask configure this for you.
Templates can use any file extension, but select_autoescape() only checks how the name ends: page.html.j2 is not escaped unless you pass enabled_extensions=("html", "j2") or similar.
Template syntax has three delimiters: {{ ... }} prints an expression, {% ... %} runs a statement such as if or for, and {# ... #} is a comment that produces no output.
Example
from jinja2 import DictLoader, Environment, Template, select_autoescape
print(Template("Hello {{ name }}!").render(name="Ann")) # Hello Ann!
env = Environment(
loader=DictLoader({ # FileSystemLoader("templates") in real projects
"greet.html": "<p>Hi {{ user }}{# not rendered #}</p>",
"greet.txt": "Hi {{ user }}",
}),
autoescape=select_autoescape(), # on for .html/.htm/.xml
)
print(env.get_template("greet.html").render(user="<b>Bo</b>"))
# <p>Hi <b>Bo</b></p>
print(env.get_template("greet.txt").render({"user": "<b>Bo</b>"}))
# Hi <b>Bo</b>Remember
- An Environment holds config and a loader; get_template loads by name
- render(**vars) or render(dict) returns a string
- {{ }} prints, {% %} executes, {# #} comments
- Environment() has autoescaping off; enable it for HTML
Watch out for
- Rendering HTML with a default Environment(), leaving output unescaped.