Flask Templates Basics

Introduction to Flask Templates

Templates are a crucial part of Flask applications, allowing you to separate your Python code (backend logic) from your HTML (frontend presentation). Flask uses the Jinja2 templating engine by default, which provides powerful features for generating dynamic HTML content.

In this tutorial, we'll explore the basics of using templates in Flask, from simple variable substitution to more complex template inheritance and macros.

Basic Template Usage

Templates in Flask are stored in the templates directory of your application. Here's how to render a simple template:

# In your Flask route
from flask import render_template

@app.route('/')
def index():
    return render_template('index.html', title='Home Page', user='John')

And here's what your template might look like:

<!-- templates/index.html -->
<html>
    <head>
        <title>{{ title }}</title>
    </head>
    <body>
        <h1>Hello, {{ user }}!</h1>
    </body>
</html>

In this example, the double curly braces are placeholders that will be replaced with the values you pass to render_template().

Template Syntax

Jinja2 templates use a special syntax for various operations:

Syntax Purpose Example
{{ ... }} Output expressions (variables, function calls) {{ user.name }}
{% ... %} Control structures (if, for, etc.) {% if user %}...{% endif %}
{# ... #} Comments (not included in output) {# This is a comment #}

Template Inheritance

One of the most powerful features of Jinja2 is template inheritance, which allows you to define a base template with common elements and extend it in child templates.

Base Template

<!-- templates/base.html -->
<html>
    <head>
        <title>{% block title %}Default Title{% endblock %}</title>
    </head>
    <body>
        <main>
            {% block content %}{% endblock %}
        </main>
    </body>
</html>

Child Template

<!-- templates/index.html -->
{% extends "base.html" %}

{% block title %}Home Page{% endblock %}

{% block content %}
    <h1>Welcome to My Flask App</h1>
    <p>This is the home page.</p>
{% endblock %}

In this example, the child template extends the base template and overrides specific blocks. This approach keeps your templates DRY (Don't Repeat Yourself) and makes maintenance easier.

Template Filters

Filters in Jinja2 transform the values of variables. They are applied using the pipe symbol:

Filter Purpose Example
safe Mark a string as safe HTML {{ content|safe }}
capitalize Capitalize the first character {{ name|capitalize }}
lower Convert to lowercase {{ text|lower }}
upper Convert to uppercase {{ text|upper }}

Best Practices

  • Use template inheritance: Create a base template with common elements and extend it in child templates
  • Keep logic minimal: Move complex logic to your Python code and keep templates focused on presentation
  • Use macros for repetitive elements: Create macros for form fields, cards, and other repeating UI components
  • Organize templates logically: Group related templates in subdirectories
  • Use url_for() for links: Always use url_for() to generate URLs rather than hardcoding them
  • Consider security: Be careful with the safe filter and only use it when necessary
Important
Templates are a core feature of Flask. Understanding them is essential for building dynamic web applications.

Security Warning

Always escape user-generated content to prevent XSS attacks. Jinja2 does this automatically for variables, but be careful when using the safe filter.