Jinja
02 / 02

Inheritance, Reuse & Security

Inheritance, Reuse & Security

Template Inheritance

{# base.html #}
<html><body>
  <header>Site Nav</header>
  {% block content %}{% endblock %}
</body></html>

{# page.html #}
{% extends "base.html" %}
{% block content %}<p>Page-specific content</p>{% endblock %}

A base template defines named blocks; child templates extend it and override just the blocks that differ — avoiding duplicated shared layout (header/footer) across many pages. {% include %} is a different tool: it inserts another template's rendered content at a specific point (a nav fragment), rather than establishing a parent/child override relationship.

Macros for Reusable Markup

{% macro input(name, value='') %}
  <input name="{{ name }}" value="{{ value }}">
{% endmacro %}

{{ input('email') }}
{{ input('name', user.name) }}

A macro factors out a repeated markup pattern (a form field, a card) into a callable, parameterized unit — similar in spirit to a function — keeping templates DRY.

Auto-Escaping & XSS

{{ comment.text }}          {# auto-escaped: safe against XSS #}
{{ trusted_html | safe }}   {# only for genuinely trusted/sanitized content #}

By default (in Flask and similar integrations), variable output is HTML-escaped, so user-controlled data containing <script> tags renders as inert text rather than executing — preventing a classic XSS vulnerability. The | safe filter opts a value out of escaping and should only ever be applied to content genuinely known to be safe, never raw user input.

Sandboxing Untrusted Templates

The default Jinja environment assumes templates come from trusted developers. SandboxedEnvironment restricts what template code can do (blocking unsafe attribute/method access), relevant when template content itself might come from a less-trusted source.

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free