Flask Template Inheritance

Template inheritance lets you define a base HTML layout once and reuse it across every page. Instead of copying the navigation bar, footer, and head section into every template, you write them once in a parent template and let child templates fill in the unique parts.

The Blueprint Analogy

Think of a building complex. Every building shares the same foundation, elevator system, and lobby design. Only the individual floors differ. Template inheritance works the same way — the base template is the foundation and shared structure, and each child template provides the unique content for its specific page.

base.html (parent)
├── <head> with CSS links — same on every page
├── <nav> navigation bar — same on every page
├── {% block content %}  ← child fills this in
│       (unique content goes here)
│   {% endblock %}
└── <footer> — same on every page

Creating the Base Template

Save this as templates/base.html:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>{% block title %}My Site{% endblock %}</title>
  <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
  <nav>
    <a href="{{ url_for('home') }}">Home</a> |
    <a href="{{ url_for('about') }}">About</a> |
    <a href="{{ url_for('contact') }}">Contact</a>
  </nav>

  <main>
    {% block content %}{% endblock %}
  </main>

  <footer>
    <p>&copy; 2024 My Website</p>
  </footer>
</body>
</html>

The {% block name %}{% endblock %} tags mark the areas that child templates can replace. Everything outside these blocks stays fixed on every page.

Creating a Child Template

Save this as templates/index.html:

{% extends 'base.html' %}

{% block title %}Home — My Site{% endblock %}

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

The {% extends 'base.html' %} line must appear at the very top of the file. It tells Jinja2 that this template inherits from base.html. Flask merges the two files before sending HTML to the browser.

What the Browser Receives

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Home — My Site</title>
  <link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
  <nav>
    <a href="/">Home</a> |
    <a href="/about">About</a> |
    <a href="/contact">Contact</a>
  </nav>

  <main>
    <h1>Welcome to My Site</h1>
    <p>This is the home page content.</p>
  </main>

  <footer>
    <p>&copy; 2024 My Website</p>
  </footer>
</body>
</html>

Another Child Template

Save this as templates/about.html:

{% extends 'base.html' %}

{% block title %}About — My Site{% endblock %}

{% block content %}
  <h1>About Us</h1>
  <p>We are a team of passionate developers.</p>
{% endblock %}

Both index.html and about.html share the same navigation, footer, and head — but each provides its own title and main content.

Default Block Content

A block in the parent template can contain default content. The child template uses this default if it does not override the block:

{# In base.html #}
{% block sidebar %}
  <p>Default sidebar content</p>
{% endblock %}

A child that does not define {% block sidebar %} automatically shows the default sidebar.

Using super() Inside a Block

When a child template wants to keep the parent's block content and add to it, use {{ super() }}:

{# In a child template #}
{% block title %}{{ super() }} — Special Page{% endblock %}
{# Result: "My Site — Special Page" #}

{{ super() }} inserts whatever the parent block contained before the child's additions.

Multiple Levels of Inheritance

Templates can inherit from other templates that themselves inherit from a base. This creates a hierarchy:

base.html
  └── dashboard_base.html  (extends base.html, adds sidebar)
        └── analytics.html (extends dashboard_base.html)

This pattern works well for admin panels or dashboards where a subset of pages shares additional layout elements beyond the global base.

How the Inheritance Flow Works

render_template('index.html')
        │
Jinja2 reads index.html
        │
Finds: {% extends 'base.html' %}
        │
Jinja2 reads base.html
        │
Merges: child blocks replace parent blocks
        │
Returns: complete HTML to Flask
        │
Flask sends: HTML to browser

Summary

Template inheritance eliminates repetition in your HTML. Write shared elements — head, nav, footer — once in a base template. Child templates extend the base and fill in named blocks with page-specific content. When you update the navigation in base.html, every page reflects the change immediately. This single-point-of-update approach saves hours of maintenance work as your project grows.

Leave a Comment

Your email address will not be published. Required fields are marked *