Skip to main content

Bootstrap

Bootstrap is a free and open-source CSS framework directed at responsive, mobile-first front-end web development.

Pre-Requisite

This notes explains briefly how we use Flask-Bootstrap for our HTML templates in Mini Project 2. You will need to read the following tutorial:

We will only explains those relevant to this mini project and more explanations can be found in those tutorials.

Base HTML

In this mini project, we have one base HTML file inside app/templates/base.html. This HTML file has the following structure following the documentation.

<!DOCTYPE html>
<html lang="en">
<head>
{% block head %}
<!-- Required meta tags -->
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>

{% block styles %}
<!-- Bootstrap CSS -->
{{ bootstrap.load_css() }} {% endblock %}

<title>Your page title</title>
{% endblock %}
</head>
<body>
<!-- Your page content -->
{% block content %}{% endblock %} {% block scripts %}
<!-- Optional JavaScript -->
{{ bootstrap.load_js() }} {% endblock %}
</body>
</html>

In order to use this file, you have to create Bootstrap5 object in your app/__init__.py file. This uses Bootstrap 5 instead of Bootstrap 4.

from flask_bootstrap import Bootstrap5
...
bootstrap = Bootstrap5(application)

The base HTML also contains the code for the navigation bar on the top:

<nav class="navbar navbar-default">
<div class="container">
<div class="navbar-header">
<button
type="button"
class="navbar-toggle collapsed"
data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1"
aria-expanded="false"
>
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="{{ url_for('index') }}">Mini Project 2</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li><a href="{{ url_for('index') }}">Home</a></li>
<li><a href="{{ url_for('questions') }}">Questions</a></li>
<li><a href="{{ url_for('challenges') }}">Challenges</a></li>
<li><a href="{{ url_for('halloffame') }}">Hall of Fame</a></li>
<li><a href="{{ url_for('users') }}">Users</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
{% if current_user.is_anonymous %}
<li><a href="{{ url_for('login') }}">Login</a></li>
{% else %}
<li><a href="{{ url_for('logout') }}">Logout</a></li>
{% endif %}
</ul>
</div>
</div>
</nav>

After the navigation bar, the code describes the content block.

{% block content %}
<div class="container">
{% with messages = get_flashed_messages() %} {% if messages %} {% for message
in messages %}
<div class="alert alert-info" role="alert">{{ message }}</div>
{% endfor %} {% endif %} {% endwith %}
</div>
{% endblock %}

The code above is used to display any flashed message. An example for a flash message is when the web application gives an alert or display an error message. In our mini project, we use this several times, for example after we create a new question inside app/routes.py, under questions() function definition, we can find the following code.

Notice that we use the code <div class="alert alert-info" role="alert"> to style our alert. You can find more info in Bootstrap's Alert Documentation.

def questions():
...
flash('Congratulations, you have created a new question.')
...

Part of the content block is the app_content block.

{% block app_content %}{% endblock %}

The above code inside base.html leaves the app_content block empty. This will be filled in the other HTML files. for example, in the index.html file, you will find:

{% extends "base.html" %} {% block app_content %}

<h1 class="display-1">Hi, {{ current_user.username }}!</h1>
... {% endblock %}

Lastly, the base.html contains the code to include any scripts we use.

{% block scripts %} {{ super() }}
<script type="module">
import * as library from "/static/__target__/clientlibrary.js";
window.library = library;
</script>
{% endblock %}
  • The line {{ super() }} is to ensure that all the other scripts in the parent HTML files are included.
  • The next line is to include our clientlibrary.js which is stored inside our app/static/__target__/ folder. Recall that the __target__ folder is produced by Transcrypt when we compile our clientlibrary.py.

Display Heading and Paragraph Styles

When you open index.html inside the template folder, you will see that we use both display-1 for header and lead for paragraph.

<h1 class="display-1">Hi, {{ current_user.username }}!</h1>

<p class="lead">Welcome ...</p>

For more options on typography, check Bootstrap's Typography Documentation.

Table Styles

We use Bootstrap's Table Style in several files like question.html, challenge.html, users.html, and halloffame.html.

The code below is from users.html.

<table class="table table-striped">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">User</th>
</tr>
</thead>
<tbody>
{% for idx in range(users|length) %}
<tr>
<th scope="row" class="lead">{{ idx+1 }}</th>
<td class="lead">#Replace Me#</td>
</tr>
{% endfor %}
</tbody>
</table>

We use table inside the class option for <table> to enable Bootstrap's Table style. We also added table-striped so that each row is having an alternately light and dark color background.

References