# Routing between pages with Jinja
# In this video... (TL;DR)
TIP
List of all code changes made in this lecture: https://diff-store.com/diff/section09__10_jinja_routing (opens new window)
Note that the code diffs are split into two. One implements a plain menu bar into the app (inside /templates
), without using url_for
.
The other implements navigation using url_for
, and that's in templates_urlfor
.
Flask has a function that, given an endpoint's function name, will give us the URL. We can use that for routing in Jinja2 as well.
Let's say we've got these two endpoints in a Flask app:
from flask import redirect, url_for
app = Flask(__name__)
account = None
@app.get("/homepage")
def home():
return "Home"
@app.get("/profile")
def profile():
if account:
return "Profile"
else:
return redirect(url_for("home"))
Let's assume for a second that the account
variable is what lets us check if the user has logged in or not.
In the second endpoint, if there is an account
, then we return "Profile". But if there isn't, we'll redirect to the homepage.
Notice that we get the URL to redirect to with the url_for("home")
function. This takes the function name for an endpoint--in this case, the function is called home
and the endpoint is /homepage
. It then returns the address to that function's endpoint, in this case, /homepage
.
We could just type the string "/homepage"
instead, but this has a few benefits:
- It becomes more useful as our apps become more complex.
- It works well with blueprints
- It means we can change endpoints later on, and as long as we keep the function names the same, our code will still work
- It's easy to pass arguments to the endpoint functions without having to think too much about query strings and things like that
So really in Flask, every time you have a link or a local address, you should be using url_for
instead of hard-coding the URL.
# Code at the start of this lecture
The code is available in the start
folder.
We've got a simple Flask app with a few sample pages:
- Home
- Login
- Signup
In each page we have a string that tells us what page it is.
In the Login and Signup pages, we also have a link to the other page (to Signup from Login, and to Login from Signup).
The links are using the standard method:
<a href="/login">Log in instead?</a>
And there are no links on the homepage.
# Code written in this lecture
First, let's change the links in the Signup and Login pages to use url_for
:
In the Signup page:
-<a href="/login">Log in instead?</a>
+<a href="{{ url_for('login') }}">Log in instead?</a>
And in the Login page:
-<a href="/signup">Sign up instead?</a>
+<a href="{{ url_for('signup') }}">Sign up instead?</a>
Then, let's also add a navbar to the base page. We could naturally do this using standard links, but we can also use url_for
:
<ul class="navigation">
<li><a href="{{ url_for('home') }}">Home</a></li>
<li><a href="{{ url_for('login') }}">Log in</a></li>
<li><a href="{{ url_for('signup') }}">Sign up</a></li>
</ul>
Notice that we're using a CSS stylesheet, which is linked in the base page like so:
<link rel="stylesheet" href="/static/css/styles.css">
We can also use url_for
here, although the syntax is slightly different:
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
Instead of passing just the endpoint name, we pass in static
. This special name also accepts a filename
argument which tells us which file to load from the /static
URL. The final URL will be /static/css/style.css
.
# Final code at the end of this lecture
This is available in the end
folder.