Flask Templates and Basic Routing

In this lesson, you'll dive into the fundamentals of building web applications with Flask. You'll learn how to create dynamic web pages using Flask templates (with Jinja2) and how to manage navigation using Flask's routing capabilities. By the end, you'll have a basic multi-page web app.

Learning Objectives

  • Understand the purpose and usage of Flask templates (Jinja2).
  • Learn how to define routes in a Flask application using decorators.
  • Create and render simple HTML templates with dynamic content.
  • Build a Flask application with multiple pages (routes) using templates.

Lesson Content

Introduction to Flask Templates (Jinja2)

Flask templates are used to separate your HTML code from your Python code. This makes your application more organized and easier to maintain. Flask uses the Jinja2 templating engine, which allows you to embed Python code within your HTML files. This lets you dynamically generate content based on data from your Python code.

To create a template, you'll typically store your HTML files in a folder named templates in the same directory as your Flask app.

Example: Let's create a simple HTML file named index.html:

<!-- templates/index.html -->
<!DOCTYPE html>
<html>
<head>
    <title>My First Flask App</title>
</head>
<body>
    <h1>Hello, {{ name }}!</h1>
    <p>Welcome to my Flask application.</p>
</body>
</html>

In this example, {{ name }} is a placeholder for a variable. We'll pass the value of name from our Python code.

Rendering Templates in Flask

To render a template, you use the render_template() function from the flask library. This function takes the template filename as an argument, and you can pass data to the template as keyword arguments.

Example: Let's update our app.py file:

# app.py
from flask import Flask, render_template

app = Flask(__name__)

@app.route("/")
def index():
    name = "User"
    return render_template("index.html", name=name)

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

In this code:

  • We import render_template.
  • The @app.route("/") decorator defines the root URL (/) for the index page.
  • The index() function renders the index.html template, passing the name variable to it.
  • When you run this, navigate to http://127.0.0.1:5000/ (or whatever address your terminal provides). You should see "Hello, User!" in your browser.

Flask Routing: Defining URLs

Flask uses decorators to define routes. A route is a URL path that, when accessed, triggers a specific function in your Flask application. The @app.route() decorator associates a function with a URL.

Example: Let's add a second page to our app.

# app.py
from flask import Flask, render_template

app = Flask(__name__)

@app.route("/")
def index():
    name = "User"
    return render_template("index.html", name=name)

@app.route("/about")
def about():
    return render_template("about.html")

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

Now, we need an about.html template (create a file templates/about.html):

<!-- templates/about.html -->
<!DOCTYPE html>
<html>
<head>
    <title>About Us</title>
</head>
<body>
    <h1>About Us</h1>
    <p>This is the about page.</p>
</body>
</html>

Now, when you visit http://127.0.0.1:5000/about, you'll see the content of the about.html page. The @app.route("/about") decorator maps this URL to the about() function.

Adding Links and Navigation

To make our application navigable, we can add links within our HTML templates. In HTML, use the <a href="/your_route">link text</a> tag to create links. For example, in index.html and about.html, let's add navigation links.

Example: Modify index.html:

<!-- templates/index.html -->
<!DOCTYPE html>
<html>
<head>
    <title>My First Flask App</title>
</head>
<body>
    <h1>Hello, {{ name }}!</h1>
    <p>Welcome to my Flask application.</p>
    <a href="/about">About</a>
</body>
</html>

And modify about.html:

<!-- templates/about.html -->
<!DOCTYPE html>
<html>
<head>
    <title>About Us</title>
</head>
<body>
    <h1>About Us</h1>
    <p>This is the about page.</p>
    <a href="/">Home</a>
</body>
</html>

Now your app should be navigable between the index page and the about page.

Deep Dive

Explore advanced insights, examples, and bonus exercises to deepen understanding.

Day 5 Extended Learning: Flask & Android Notifications

Day 5 Extended Learning: Flask & Android Notifications - Expanding Your Horizons

Expanding on Flask Fundamentals

Now that you've built a basic multi-page Flask application using templates and routing, let's explore ways to make your web application more dynamic, efficient, and interactive. We'll delve into advanced template features, error handling, and the potential for integrating with external APIs. This lays the groundwork for understanding how to eventually integrate with Android system notifications, which we'll touch upon later in the learning journey.

Deep Dive: Advanced Jinja2 Templating and Flask Context

Jinja2 is more powerful than simply displaying static and dynamic text. Let's look at some advanced features:

  • Template Inheritance: Create a base template with common elements (header, footer, navigation). Then, other templates can "inherit" from this base, overriding or adding content to specific blocks. This promotes code reuse and consistency.
  • Filters: Jinja2 provides filters to modify data within your templates. For example, `{{ my_string | upper }}` will render `my_string` in uppercase. Common filters include `lower`, `capitalize`, `truncate`, `date`, etc.
  • Custom Filters and Functions: You can define your own filters and functions to perform more complex data transformations or calculations directly in your templates. This can be achieved by using the `app.add_template_filter()` and `app.add_template_global()` functions in your Flask app.
  • Flask Context: Flask automatically makes certain variables and functions available within your templates. For instance, `url_for()` is used to generate URLs based on your routes' names. You can also pass your own variables (e.g., user data, settings) from your Flask routes to the templates using the `render_template()` function. Understanding the context is crucial for managing your application's data flow.

Consider the following example for template inheritance:

                
                    {# base.html - Base template #}
                    <!DOCTYPE html>
                    <html>
                    <head>
                        <title>{% block title %}My App{% endblock %}</title>
                    </head>
                    <body>
                        <header>
                            <h1>My Website</h1>
                        </header>
                        <main>
                            {% block content %}{% endblock %}
                        </main>
                        <footer>
                            <p>© 2023</p>
                        </footer>
                    </body>
                    </html>

                    {# index.html - Child template #}
                    {% extends "base.html" %}
                    {% block title %}Home Page{% endblock %}
                    {% block content %}
                        <h2>Welcome!</h2>
                        <p>This is the homepage.</p>
                    {% endblock %}
                
            

Bonus Exercises

Here are some exercises to further solidify your understanding:

  1. Template Inheritance Challenge: Create a Flask application with at least three pages: a base page, a home page, and an about page. Use template inheritance to structure your HTML, ensuring the header, footer, and navigation are consistent across all pages, and only the content area varies. Use different styles and content for each page.
  2. Filter Fun: In your Flask application, create a route that passes a string variable to a template. Apply the `upper` filter to display the string in uppercase. Also, experiment with other filters, such as `lower`, `truncate`, or a custom filter of your own design. For instance, create a filter that counts the number of vowels in a string and display the value within a template.

Real-World Connections

These concepts are incredibly valuable in real-world web development:

  • E-commerce Websites: Template inheritance keeps the design consistent while displaying product details, shopping carts, and checkout pages. Filters are used for formatting prices, dates, and other data.
  • Blog Platforms: A base template provides the common structure (header, navigation, sidebar). Individual blog posts are then rendered within this base, with content dynamically populated.
  • Web Applications with User Authentication: You can use context to securely pass user details from the backend to the frontend for displaying user-specific data and controling access to pages.

Challenge Yourself

For a more challenging exercise, consider the following:

  1. Dynamic Navigation: Modify your Flask application to dynamically generate navigation links based on a list of page names or routes stored in a configuration file or a database. This allows for easy changes to your website's navigation without modifying the HTML templates directly. Consider creating a context processor to handle generating navigation items.

Further Learning

To expand your knowledge further, explore these topics:

  • Flask Extensions: Learn about Flask extensions like Flask-SQLAlchemy (for database interaction), Flask-Login (for user authentication), and Flask-WTF (for form handling).
  • REST APIs with Flask: Explore creating RESTful APIs using Flask and techniques for handling different HTTP methods (GET, POST, PUT, DELETE).
  • Progressive Web App (PWA) Basics: Start learning about the core components of PWAs, including service workers, manifest files, and how to make your web application work offline. This knowledge will eventually be crucial to add Android notification support.

Interactive Exercises

Create a Contact Page

Create a new route and template for a 'Contact' page. The route should be `/contact`, and the template should display a simple form (you don't need to make it functional). Include a navigation link from the other pages to the contact page. The `contact.html` file should be located in the templates folder.

Dynamic Greetings

Modify the `index()` function to accept a name as a URL parameter (e.g., `/hello/<name>`). Update the `index.html` template to greet the provided name. For example, if someone visits `/hello/Alice`, the page should say 'Hello, Alice!'

Template Inheritance Brainstorm

Think about how you could create a base template (a layout) that contains common elements like headers, footers, and navigation. How would this simplify creating multiple pages? Sketch out an example of a base template and how child templates might inherit from it. (Don't implement it yet, just brainstorm).

Knowledge Check

Question 1: What is the purpose of Flask templates?

Question 2: Which function is used to render a template in Flask?

Question 3: What is the purpose of the `@app.route()` decorator?

Question 4: Where are templates typically stored in a Flask project?

Question 5: How do you pass data from your Python code to a template?

Practical Application

Build a simple website for a fictional business. Include a home page, an about page, and a contact page, all using templates and routing. Add a menu to navigate between pages.

Key Takeaways

Next Steps

Prepare for the next lesson by reviewing the basics of HTML and CSS, especially focusing on the structure of HTML and basic styling elements. We will explore how to apply CSS and static resources in flask next.

Your Progress is Being Saved!

We're automatically tracking your progress. Sign up for free to keep your learning paths forever and unlock advanced features like detailed analytics and personalized recommendations.

Next Lesson (Day 6)