Routing and Templating Practice

1. Add a Supplies Page

A user may want to see what supplies we will need in our kitchen to make the recipes posted on our site. This will give us practice with bringing data into our application, and sending that data along the route to the template.

Follow Along with the Instructor

Practice with the instructor. Not an exact replacement for the written directions below.

  • Practice with routing and templating, and bringing in data to your app and template, by adding a Supplies page.

SET UP: Download supplies.csv and add to your root directory

Download supplies.csv

root
└── vscode
└── flaskapp
├── venv
├── recipes.csv
├── supplies.csv
└── ...
<nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
    ...
    <ul class="navbar-nav me-auto mb-2 mb-md-0">
        <li class="nav-item">
            <a class="nav-link" href="{{ url_for('render_about') }}">About</a>
        </li>
        <!-- Add link to Supplies here -->

CREATE ROUTE: In app.py, add a route called /supplies

The supplies route should:

  • have access to a nested list of supplies
  • render the template supplies.html
  • pass on the nested supplies list to the HTML template

HANDLE DATA: Bring in the supplies list from supplies.csv

Write a function in app.py that reads in supplies.csv as a nested list, where the structure is [[supply-name, description], [], ...].

# place this function near our other open CSV function
def get_all_supplies():
    # add code here
    return all_supplies

RENDER TEMPLATE: Create a new template page to display all supplies

This HTML template page should:

  • have a page title that says “Supplies”
  • include required template code
  • display the following text:
<h1 class="display-4">Kitchen Supplies</h1>

<p class="lead">To cook the recipes found on this site, you will need a selection of kitchen tools. The following is a list of the essentials.</p>

<!-- Place supplies table here -->
  • display the nested supplies list as a table
  • supplies table should be styled using Bootstrap (Content > Tables)

2. Add Recipe Details Pages

When we click on a recipe in the home page, the site should open a page with details about that recipe. This will give us practice with writing routes that both require data and pass data along to the HTML template.

Follow Along with the Instructor

Practice with the instructor. Not an exact replacement for the written directions below.

  • Practice with routing and templating, and bringing data in and out of your route, by adding a link to a details page for each recipe on the home page.

Add a link around each card, then replace the hashtag # in the link to a new route.

...
<div class="col-12 col-md-6 col-lg-4 col-xl-3 mb-5">
    <a href="#">
        <div class="card h-100 hvr-grow" style="width: 18rem;">
            ...
        </div>
    </a>
</div>
...

CREATE ROUTE: In app.py, add a route called /recipes/<recipe>

The recipes route should:

  • have access to the recipe’s slug through the <recipe> variable
  • use that slug to find the dictionary for that particular recipe
  • render the template recipe.html
  • pass on the relevant recipe dictionary to the HTML template

Challenge

  • Replace the numeric rating value with a number of ⭐️ instead (hint: copy the star to begin)
Possible Solution: Try it First
one_recipe['rating'] = '⭐️ ' * int(one_recipe['rating'])

RENDER TEMPLATE: Create a new template page recipe.html to display details for a single recipe

This HTML template page should:

  • be titled with the name of the recipe
  • include required template code
  • display the details for the single recipe card clicked on in the home page
  • replace the ALL CAPS elements in the code below using Jinja, and as needed, referencing the recipe data pulled into the page
<h1 class="display-4">RECIPE NAME</h1>

<div class="row row-cols-1 row-cols-lg-2">
    <div class="col">
        <img src="IMAGE SOURCE" class="img-fluid py-3"
            alt="RECIPE NAME">
    </div>
    <div class="col">
        <p class="pt-3">RECIPE DESCRIPTION</p>
        <p>RECIPE RATING</p>
        <div class="d-grid gap-2 d-md-block row-gap-2">
            <a href="RECIPE URL" target="_blank" type="button" class="btn btn-primary">Get this Recipe</a>
            <a href="LINK TO HOME PAGE" target="_blank" type="button" class="btn btn-secondary">Find Another Recipe</a>
        </div>
    </div>
</div>

Did you notice? We have 10 recipes, could have more, and yet we have only ONE TEMPLATE that handles all of those pages!

Quiz Yourself: Where is the Data? 🤔

which data is being passed in which route quiz

Is data being passed between the start and end of each orange arrow? If so, what is that data? Answer for each arrow:

Interaction 1: Arrow #1

Is data being passed between the user clicking on a recipe in the home page and the function in our route?

Answer to #1

Yes

We need to know which recipe the user clicked on. The route is expecting the "slug" for a recipe. This will become a parameter in our function, and a local variable we can use to look up the details for the recipe clicked on.

Interaction 1: Arrow #2

Is data being passed between the route and the recipe details page?

Answer to #2

Yes

We need to send along the dictionary of data associated with the recipe we clicked on so the page's template can unpack and display the details for this single recipe.