Python > Web Development with Python > Flask > Templates (Jinja2)

Template Inheritance in Flask with Jinja2

This snippet demonstrates template inheritance in Flask using Jinja2. Template inheritance allows you to define a base template with common elements and then extend it in other templates, reducing code duplication and maintaining consistency.

Creating a Base Template (base.html)

This is the base template. It defines the basic structure of the website, including the HTML document, head, navigation, content area, and footer. The `{% block ... %}` tags define areas that can be overridden by child templates. `{% block title %}` and `{% block content %}` are placeholders for dynamic content.

<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}My Website{% endblock %}</title>
</head>
<body>
    <nav>
        <a href="/">Home</a> | <a href="/about">About</a>
    </nav>
    <hr>
    <div class="content">
        {% block content %}{% endblock %}
    </div>
    <hr>
    <footer>
        &copy; 2023 My Website
    </footer>
</body>
</html>

Extending the Base Template (index.html)

This template extends the `base.html` template. The `{% extends 'base.html' %}` tag specifies the parent template. The `{% block title %}` and `{% block content %}` blocks override the corresponding blocks in the base template, providing specific content for the home page.

{% extends 'base.html' %}

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

{% block content %}
    <h1>Welcome to the Home Page!</h1>
    <p>This is the main content of the home page.</p>
{% endblock %}

Extending the Base Template (about.html)

This template also extends the `base.html` template, providing specific content for the about page.

{% extends 'base.html' %}

{% block title %}About{% endblock %}

{% block content %}
    <h1>About Us</h1>
    <p>This is the about page.</p>
{% endblock %}

Flask App Code

This Flask app defines two routes: `/` for the home page and `/about` for the about page. Each route renders a different template, which extends the base template.

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/about')
def about():
    return render_template('about.html')

if __name__ == '__main__':
    app.run(debug=True)

Folder Structure

my_app/ app.py templates/ base.html index.html about.html

Concepts Behind the Snippet

Template inheritance is a powerful technique for creating a consistent look and feel across your website while minimizing code duplication. It promotes a DRY (Don't Repeat Yourself) approach to web development.

Real-Life Use Case

Consider a large e-commerce website. Many pages share a common layout (header, footer, navigation). Using template inheritance, you can define these common elements in a base template and then create specific templates for product pages, category pages, and checkout pages that inherit from the base template.

Best Practices

  • Keep your base templates simple and focused on defining the overall structure.
  • Use meaningful block names to make your templates easier to understand.
  • Avoid deeply nested template inheritance hierarchies, as they can become difficult to manage.
  • Document your base templates to explain the purpose of each block.

Interview Tip

Be prepared to explain the benefits of template inheritance and how it helps improve code maintainability and reduces redundancy. Provide an example of how you would use template inheritance in a real-world web application.

When to Use Them

Template inheritance is ideal when you have multiple pages that share a common layout or structure. It's a best practice for almost all web applications that use template engines.

Memory Footprint

Template inheritance generally doesn't significantly increase memory usage. The template engine caches the compiled templates, so the overhead is minimal.

Alternatives

  • Components/Partials: Instead of full inheritance, use components or partials for smaller reusable elements.
  • CSS Frameworks: Utilize CSS frameworks like Bootstrap or Tailwind CSS to enforce a consistent look and feel.

Pros

  • Reduced Code Duplication: Avoids repeating common elements across multiple pages.
  • Improved Maintainability: Changes to the base template are automatically reflected in all child templates.
  • Consistent Look and Feel: Ensures a consistent user experience across the website.

Cons

  • Increased Complexity: Can increase the complexity of the template structure.
  • Overriding Issues: Incorrectly overriding blocks can lead to unexpected results.

FAQ

  • Can I have multiple levels of template inheritance?

    Yes, you can have multiple levels of template inheritance. A child template can extend another template, which in turn extends a base template. However, it's generally recommended to keep the inheritance hierarchy relatively shallow to avoid complexity.
  • How do I include content from the parent template in a child template block?

    You can use the `{{ super() }}` function within a block in a child template to include the content from the parent template's block. For example: html {% extends 'base.html' %} {% block content %} {{ super() }}

    Additional content on the home page.

    {% endblock %}
  • What happens if I don't define a block in a child template?

    If you don't define a block in a child template, the content from the corresponding block in the parent template will be used. This allows you to create pages that inherit the default content from the base template.