Home > Courses > Flask: Python Web Development > Create Consistent layout using Jinja

Create Consistent layout using Jinja

Subject: Flask: Python Web Development
Looking at the previous lesson and the ones related to the School Grading System you must have noticed some annoying repitition of code in the templates html files


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Students Record</title>
</head>

<body>
<h2>School Grading System</h2>
    <hr/>
    <a href="/student">Students</a> | 
    <a href="#">Subjects</a> | 
    <a href="#">Instructor</a> | 
    <a href="#">Score Sheet</a> 
    <hr/>
    <h2>See Student Record</h2>
  
<a href="/">Back to home</a><br/>
....


This code is supposed to be a layout with navigations that appears on all the HTML templates files, but as we introduced more HTML files, if we need to make a change to the navigation link for example, we will have to do this across several of this files which is a very bad practice that can turn to a nightmare to maintain as the code base of project grows.

Fortunately, jinja supports template inheritance, allowing the creation of a base or layout template that you can extend in other or child templates, encouraging code reuse and a consistent layout across different pages of out project.

Create a base or layout template
Create a new template named layout.html in a templates folder:

templates/layout.html


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
School Grading System - {% block title %}{% endblock title %}
</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>

    <header>
<h1>School Grading System</h1>
    </header>


    <nav>
        <a href="/">Home</a>
        <a href="student">Add Student</a>
         <a href="seestudents">See  Students</a>
    </nav>
    <div class="container">
   <h2> {% block subheading %}{% endblock subheading %}</h2>

{% block content %}
<p>No messages.</p>
{% endblock content %}
    </div>
<footer>
Designed and Developed Ben Onuorah
</footer>
</body>
</html>


Some styling to beautify our web app
Notice this line in the layout.html
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">

This mean that I have added a CSS style file to the static folder which is now refrenced by the layout and as such all the templates that will extend our layout with the beautifully styled.

static/style.css

body {
        font-family: Arial, sans-serif;
        margin: 0;
        padding: 0;
    }
    header {
        background-color: #333;
        color: white;
        padding: 10px 20px;
        text-align: center;
    }
    nav {
        background-color: #444;
        padding: 10px 0;
        text-align: center;
    }
    nav a {
        color: white;
        text-decoration: none;
        padding: 10px 20px;
    }
    nav a:hover {
        background-color: #666;
    }
    .container {
        max-width: 800px;
        margin: 20px auto;
        padding: 0 20px;
    }
    h1, h2 {
        margin-bottom: 10px;
    }
    p {
        margin-bottom: 20px;
    }
    footer {
        background-color: #333;
        color: white;
        padding: 10px 20px;
        text-align: center;
    }


Base or layout template is designed to provide a consistent structure for your project while allowing flexibility in specific parts of the content through Jinja’s block functionality.

Extend the base or layout template
Now create child templates to extend the base or layout, in this example I modified our three views template to extend layout.html and fill in these blocks with their specific content.

templates/index.html

{% extends 'layout.html' %}
{% block title %}Welcome{% endblock title %}
<h2>
{% block subheading %}Home{% endblock subheading %}</h2>
{% block content %}
<p>
 Welcome to my web app
</p>
{% endblock content %}



templates/student.html

<!DOCTYPE html>
{% extends 'layout.html' %}
{% block title %}Add Student{% endblock title %}
<h2>
{% block subheading %}Add Student{% endblock subheading %}</h2>
{% block content %}
  
{% if msg %}
  <p><b>{{ msg }}</b></p>
{% endif %}
    <form method="POST" action ="/addstudent">
      Surname: <br/>
      <input type="text" name="surname" />
      <br/>
      
      Other names: <br/>
      <input type="text" name="othernames" />
      <br/>
      
      Address: <br/>
      <textarea name="address"></textarea>
      
      <br/>
      <input type="submit" name="Save"/>
  </form>

{% endblock content %}


templates/seestudents.html

<!DOCTYPE html>
{% extends 'layout.html' %}
{% block title %}See Students{% endblock title %}
<h2>
{% block subheading %}See Students{% endblock subheading %}</h2>
{% block content %}

<table width="100%" border=1> 
            <tr> 
              <th>Id</th> 
              <th>Surname</th> 
              <th>Othernames</th> 
              <th>Address</th>
            </tr> 

            {%for rec in students%} 
               <tr> 
                 <td>{{rec[0]}}</td> 
                 <td>{{rec[1]}}</td> 
                 <td>{{rec[2]}}</td> 
                 <td>{{rec[3]}}</td> 
                </tr> 
            {%endfor%} 
          </table>   

{% endblock content %}



Note: The vhild templates also contain {% block %} tags. By providing the block’s name as an argument, you’re connecting the blocks from the child template with the blocks from the base or layout template.

Now you can run the app.py and see the result on the web browser



By: Benjamin Onuorah

Comments

No Comment yet!

Login to comment or ask question on this topic


Previous Topic Next Topic

Supported by