When several templates need the same HTML, or one template repeats a complex fragment, a Jinja macro keeps that markup in one place. Think of it like a Python function: define it once, pass arguments when needed, and render its output where it belongs. A login template, for example, imports macros.jinja and calls a validation-errors macro beneath form fields. section 8.2.2
{% macro validation_errors(errors) %}
{% if errors %}
{% for error in errors %}
<div class="text-danger small">{{error}}</div>
{% endfor %}
{% endif %}
{% endmacro %}
The validation_errors(errors) macro accepts a field’s error list. It checks whether the list has entries, then renders each message as small red text; an empty list produces no error markup. section 8.2.2
Macros also keep shared templates focused. A flash-message macro generates Bootstrap toast markup instead of placing that substantial HTML directly in base.html. Separate JavaScript shows the toasts after the page renders; the macro generates their markup, not their browser behavior. A navigation macro in the same shared template chooses Login or Logout from the user’s authentication state. section 8.3.1 section 9.1
Comments and modal dialogs
On a post page, a macro renders each comment as the template loops through them. Another supplies the HTML for a Bootstrap modal used to create or edit comments. These macros live in a content-specific file imported by the post template, keeping that page’s repeated and specialized markup separate. section 11.7.3 section 11.8.1
Use a macro when a piece of template output has a clear job and would otherwise be repeated or crowd the surrounding page. Put shared interface elements where inheriting templates can use them, and keep content-specific elements with their content templates. section 8.3.1 section 11.7.3
