Skip to content

Template Inheritance

sachin soman edited this page Mar 17, 2021 · 5 revisions

Inheritance

Lets look at two different Html files:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">

    {% if title %}
    <title>Django Blog- {{title}}</title>
    {% else %}
    <title>Django Blog</title>
    {% endif %}

</head>
<body>

    {% for post in post %}
         <h1>{{ post.title }}</h1>
         <p>By {{ post.author }} on {{  post.date_posted }}</p>

    {% endfor %}

</body>
</html>

And compare this with the next Html file:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    {% if title %}
    <title>Django Blog- {{title}}</title>
    {% else %}
    <title>Django Blog</title>
    {% endif %}</head>
<body>
<h1>Blog About!</h1>
</body>
</html>

we see that both these files share almost 90 percent of code in such cases its best to use inheritance to make a website this is because it will be easier to maintain and if some global changes have to be made it can be done in a single file itself instead of going to each page to change it. Coding with inheritance is more robust: For this lets make a base Html file which will be inherited by both the codes we shared above.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    {% if title %}
    <title>Django Blog- {{title}}</title>
    {% else %}
    <title>Django Blog</title>
    {% endif %}</head>
<body>

{% block content %}
{% endblock %}

</body>
</html>

So the base Html will have something called a 'block' this is where we add the elements which vary between sites.

Using inheritance on home.html and about.html home.html:

{% extends "blog/base.html" %}

{% block content %}
    {% for post in post %}
         <h1>{{ post.title }}</h1>
         <p>By {{ post.author }} on {{  post.date_posted }}</p>

    {% endfor %}
{% endblock content %}

and about.html:

{% extends "blog/base.html" %}
{% block content %}
<h1> about hehe</h1>
{% endblock content%}

This example really shows the power of inheritance we with a base template can modify all the pages which inherit it and at the same time, we can override them in each page to customize it. The about.html simply extends the base.html and inserts the content in the specified blocks here the block was named content and all stuff was pasted into it.

Advanced Example

A really useful scenario is when we are trying to add styling to the website like the use of bootstrap. In that case, instead of adding the header tag on each page, we can simply add the headers to the base class and every page will inherit it.

base.html

{% load static %}
<!DOCTYPE html>
<html>
<head>

    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">

    <link rel="stylesheet" type="text/css" href="{% static 'blog/main.css' %}"> 

    {% if title %}
        <title>Django Blog - {{ title }}</title>
    {% else %}
        <title>Django Blog</title>
    {% endif %}
</head>
<body>
    <header class="site-header">
      <nav class="navbar navbar-expand-md navbar-dark bg-steel fixed-top">
        <div class="container">
          {% comment %} <a class="navbar-brand mr-4" href="{% url 'blog-home' %}">Django Blog</a> {% endcomment %}
          <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarToggle" aria-controls="navbarToggle" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
          </button>
          <div class="collapse navbar-collapse" id="navbarToggle">
            <div class="navbar-nav mr-auto">
               <a class="nav-item nav-link" href="{% url 'home' %}">Home</a>
              <a class="nav-item nav-link" href="{% url 'about' %}">About</a> 
            </div>
            <!-- Navbar Right Side -->
            <div class="navbar-nav">

            </div>
          </div>
        </div>
      </nav>
    </header>
    <main role="main" class="container">
      <div class="row">
        <div class="col-md-8">
          {% block content %}{% endblock %}
        </div>
      </div>
    </main>

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
</body>
</html>