Python Flask – Bootstrap Html Template Layout with Navigation

Photo by Tetyana Kovyrina from Pexels

Overview

This tutorial is a how-to for using an html layout with Bootstrap CDN. The layout has an App Bar menu that lets you navigate to a Home, Users Table, Registration, and Login pages. The menu item will be displayed as active if the path corresponds to the menu item.

Github – Source Code

Get Source Code

Prerequisites

Install Python Flask

pip install Flask

HTML Templates

Create the following templates under the “.templates” folder:

The .\templates should be at the root of your python application.

  • layout.html
  • login.html
  • registraion.html
  • usersTable.html

Also create a folder labeled “.\static to store images. In this example you can get the images from the GitHub repo or use your own.

Layout

layout.html – HTML Form for the layout.

This layout will wrap all other content inside using block content,

 {% block content %}{% endblock %}

To highlight the active menu item use the request.endpoint property.

<li {% if request.endpoint == 'index' %} class="nav-item active" {% else %} class="nav-item" {% endif %}>
   <a class="nav-link" href="/">Home <span class="sr-only">(current)</span></a>
</li>

The code for the layout.html

<!doctype html>
<title>- Flask Template Demo</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
  <a class="navbar-brand" href="#">FLASK CRUD APP</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarText" aria-controls="navbarText" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>
  <div class="collapse navbar-collapse" id="navbarText">
    <ul class="navbar-nav mr-auto">
      <li {% if request.endpoint == 'index' %} class="nav-item active" {% else %} class="nav-item" {% endif %}>
        <a class="nav-link" href="/">Home <span class="sr-only">(current)</span></a>
      </li>
      <li {% if request.endpoint == 'users' %} class="nav-item active" {% else %} class="nav-item" {% endif %}>
        <a  class="nav-link" href="/users">Users <span class="sr-only">(current)</span></a>
      </li>
      <li {% if request.endpoint == 'register' %} class="nav-item active" {% else %} class="nav-item" {% endif %}>
        <a class="nav-link" href="/register">Form <span class="sr-only">(current)</span></a>
      </li>
      <li {% if request.endpoint == 'login' %} class="nav-item active" {% else %} class="nav-item" {% endif %}>
        <a class="nav-link" href="/login">Login</a>
      </li>
    </ul>
  </div>
</nav>
<section class="content">  
  {% block content %}{% endblock %}
  <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" ></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
  
</section>

Home Page

home.html will be the landing page. To use the layout.html add {% extends ‘layout.html’ %} at the top of the page.

{% extends 'layout.html' %}
{% block content %}
<section id="section-about" class="bg-grey">
  <div class="container">
      <div class="row pt-4">
          <div class="col-md-6 col-sm-12">
              <img src="{{url_for('static', filename=home_image)}}" alt="about image" class="img-responsive">
          </div>
          <div class="col-md-1"></div>
          <div class="col-md-5 col-sm-12">
              <div class="about-box">
                  <h2 class="box-title">Python Flask Example</h2>
                  <div class="tiny-border"></div>
                  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
                  <ul class="list-style-1">
                      <li>Donec malesuada urna porta tellus feugiat</li>
                      <li>Nullam consequat lacus non luctus finibus.</li>
                      <li>Interdum et malesuada fames ac ante</li>
                      <li>Nam justo ipsum, sagittis sed hendrerit ac</li>
                  </ul>
                  <div class="divider-single"></div>
                  <a href="#" class="btn btn-primary btn-small">Get Started</a>                                
              </div>
          </div>
      </div>
  </div>        
</section>
{% endblock %}

Registration Page

registration.html – Will be a static registration page we can navigate to. Once again add {% extends ‘layout.html’ %} at the top of the page.

{% extends 'layout.html' %}
{% block content %}
<section id="section-about" class="bg-grey">
  <div class="container">
      <div class="row pt-4">
          <div class="col-md-6 col-sm-12">
              <img src="{{url_for('static', filename=home_image)}}" alt="about image" class="img-responsive">
          </div>
          <div class="col-md-1"></div>
          <div class="col-md-5 col-sm-12">
              <div class="about-box">
                  <h2 class="box-title">Python Flask Example</h2>
                  <div class="tiny-border"></div>
                  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
                  <ul class="list-style-1">
                      <li>Donec malesuada urna porta tellus feugiat</li>
                      <li>Nullam consequat lacus non luctus finibus.</li>
                      <li>Interdum et malesuada fames ac ante</li>
                      <li>Nam justo ipsum, sagittis sed hendrerit ac</li>
                  </ul>
                  <div class="divider-single"></div>
                  <a href="#" class="btn btn-primary btn-small">Get Started</a>                                
              </div>
          </div>
      </div>
  </div>        
</section>
{% endblock %}

Login Page

login.html – Login form. Also add {% extends ‘layout.html’ %} at the top of the page.

{% extends 'layout.html' %}
{% block content %}
<div id="login">
  <h3 class="text-center text-white pt-5">Login form</h3>
  <div class="container">
      <div id="login-row" class="row justify-content-center align-items-center">
          <div id="login-column" class="col-md-6">
              <div id="login-box" class="col-md-12">
                  <form id="login-form" class="form" action="" method="post">
                      <h3 class="text-center text-info">Login</h3>
                      <div class="form-group">
                          <label for="username" class="text-info">Username:</label><br>
                          <input type="text" name="username" id="username" class="form-control">
                      </div>
                      <div class="form-group">
                          <label for="password" class="text-info">Password:</label><br>
                          <input type="text" name="password" id="password" class="form-control">
                      </div>
                      <div class="form-group">
                          <label for="remember-me" class="text-info"><span>Remember me</span> <span><input id="remember-me" name="remember-me" type="checkbox"></span></label><br>
                          <input type="submit" name="submit" class="btn btn-info btn-md" value="submit">
                      </div>
                      <div id="register-link" class="text-right">
                          <a href="./register" class="text-info">Register here</a>
                      </div>
                  </form>
              </div>
          </div>
      </div>
  </div>
</div>
{% endblock %}

App.js

And finally the Python file. The random_image() function returns a random image from the “.\static” folder every time the home page is loaded.

from flask import Flask, render_template, request
import os
import random

app = Flask(__name__)

def random_image():
    """
    Return a random image from the ones in the static/ directory
    """
    img_dir = "./static"
    img_list = os.listdir(img_dir)
    return random.choice(img_list)


@app.route('/', methods=["GET", "POST"])
def index():   
   image = random_image()   
   return render_template('home.html', home_image = image)

@app.route('/register', methods=["GET", "POST"])
def register():
   return render_template('registration.html')

@app.route('/login', methods=["GET", "POST"])
def login():
   return render_template('login.html')


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

[“GET”, “POST”]

In the login and registration action we add the methods=[“GET”, “POST”] so the action can either get (display view) or post send data from form to the action.

@app.route('/login', methods=["GET", "POST"])
def edit():