In traditional fashion, we will finish up with a contact form. The difference this time is that this one actually does something!
We will use the power of Flask to send our contact form information through to a thankyou page, and if it were on a real server we could even pass on the information as an email. We'll also learn how to integrate Bootstrap into our Flask apps.
In this activity, we will set up a base template using Bootstrap. This will provide a consistent layout and styling for our web application.
We will re-use many of the same filenames in this activity. You may rename these if you would like to keep them, otherwise, just overwrite them with the new code.
base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}My Flask App{% endblock %}</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container">
<a class="navbar-brand" href="/">Flask Bootstrap Demo</a>
</div>
</nav>
<div class="container mt-4">
{% block content %}{% endblock %}
</div>
<footer class="mt-5 py-3 bg-light">
<div class="container text-center">
<span class="text-muted">© 2024 Flask Bootstrap Demo</span>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
This is an HTML template that serves as the base for our web pages.
The <link> tag in the <head> section loads Bootstrap's CSS.
The <div class="container mt-4"> creates a main content area with some margin at the top.
The {% block %} tag inside the container allows child templates to insert content into this area.
The <script> tag at the end loads Bootstrap's JavaScript for interactive components.
Create this file as base.html in your templates folder.
You don't need to run anything yet, but take a moment to understand the structure of this HTML file.
In this activity, we will create a contact form using Bootstrap classes. This form will inherit from our base template and use Bootstrap's form styling.
contact.html
{% extends "base.html" %}
{% block title %}Contact Us{% endblock %}
{% block content %}
<h2>Contact Us</h2>
<form method="POST" action="{{ url_for('contact') }}">
<div class="mb-3">
<label for="name" class="form-label">Name</label>
<input type="text" class="form-control" id="name" name="name" required>
</div>
<div class="mb-3">
<label for="email" class="form-label">Email address</label>
<input type="email" class="form-control" id="email" name="email" required>
</div>
<div class="mb-3">
<label for="message" class="form-label">Message</label>
<textarea class="form-control" id="message" name="message" rows="3" required></textarea>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
{% endblock %}
This template extends base.html, which means it inherits the structure we defined earlier.
The {% extends %} and {% block %} tags are Jinja2 template inheritance features.
The form uses the POST method, which we'll explain in the next activity.
{{ url_for('contact') }} is a Flask function that generates the URL for the contact route.
Create this file as contact.html in your templates folder.
Don't worry about the Flask route yet; we'll create that in the next activity.
In this activity, we will create a Flask route to handle both GET and POST requests for our contact form.
app.py
from flask import Flask, render_template, request, redirect, url_for
app = Flask(__name__)
@app.route('/contact', methods=['GET', 'POST'])
def contact():
if request.method == 'POST':
name = request.form['name']
email = request.form['email']
message = request.form['message']
# Here you would typically save this data or send an email
return redirect(url_for('thankyou', name=name, message=message))
return render_template('contact.html')
@app.route('/thankyou')
def thankyou():
name = request.args.get('name')
message = request.args.get('message')
return render_template('thankyou.html', name=name, message=message)
if __name__ == '__main__':
app.run(debug=True)
This Flask route handles both GET and POST requests for the /contact URL.
GET and POST are HTTP methods:
GET is used to request data from a server. When you type a URL in your browser, you're making a GET request.
POST is used to submit data to be processed by the server. When you submit a form, you're typically making a POST request.
The if request.method == 'POST': checks if the request is a POST request (i.e. if the form was submitted).
If it's a POST request, we retrieve the form data using request.form['field_name'].
After processing the form data, we redirect to a thank you page using redirect(url_for('thankyou', ...)).
If it's a GET request, we simply render the contact form template.
The thankyou route retrieves the name and message from the URL parameters using request.args.get().
Add these routes to your Flask application.
Run your Flask app and navigate to /contact.
Fill out the form and submit it to see what happens.
In this activity, we will create a thank you page that displays the submitted name and message.
thankyou.html
{% extends "base.html" %}
{% block title %}Thank You{% endblock %}
{% block content %}
<h2>Thank You, {{ name }}!</h2>
<p>We have received your message:</p>
<blockquote class="blockquote">
<p class="mb-0">{{ message }}</p>
</blockquote>
<a href="{{ url_for('contact') }}" class="btn btn-primary">Send Another Message</a>
{% endblock %}
This template also extends base.html, maintaining a consistent layout.
{{ name }} and {{ message }} are Jinja2 placeholders that will be replaced with actual values passed from the Flask route.
The blockquote class is a Bootstrap style for quoting content.
Create this file as `thankyou.html` in your templates folder.
Submit the contact form again and see how the thank you page looks.
Try submitting with different names and messages.
Now it's your turn to add some features to this basic setup. Here are some challenges for you to try:
Add a subject field to the contact form and display it on the thank you page.
Use Bootstrap to add some more style and structure to your form.
Create a navigation menu in base.html with links to Home, About, and Contact pages.
Remember to commit and push your code when done! Here are the terminal commands to do so:
Commit your changes with a meaningful message:
git commit -am "Your message here"
Note: The -a flag automatically stages all modified files before committing, -m is to add a message.
Push your changes to GitHub:
git push origin main