(window.webpackJsonp=window.webpackJsonp||[]).push([[110],{632:function(t,a,s){"use strict";s.r(a);var e=s(56),n=Object(e.a)({},(function(){var t=this,a=t.$createElement,s=t._self._c||a;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("ul",[s("li",[s("a",{attrs:{href:"#routing-between-pages-with-jinja"}},[t._v("Routing between pages with Jinja")]),t._v(" "),s("ul",[s("li",[s("a",{attrs:{href:"#in-this-video-tldr"}},[t._v("In this video... (TL;DR)")])]),t._v(" "),s("li",[s("a",{attrs:{href:"#code-at-the-start-of-this-lecture"}},[t._v("Code at the start of this lecture")])]),t._v(" "),s("li",[s("a",{attrs:{href:"#code-written-in-this-lecture"}},[t._v("Code written in this lecture")])]),t._v(" "),s("li",[s("a",{attrs:{href:"#final-code-at-the-end-of-this-lecture"}},[t._v("Final code at the end of this lecture")])])])])]),t._v(" "),s("h1",{attrs:{id:"routing-between-pages-with-jinja"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#routing-between-pages-with-jinja"}},[t._v("#")]),t._v(" Routing between pages with Jinja")]),t._v(" "),s("h2",{attrs:{id:"in-this-video-tl-dr"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#in-this-video-tl-dr"}},[t._v("#")]),t._v(" In this video... (TL;DR)")]),t._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),s("p",[t._v("List of all code changes made in this lecture: "),s("a",{attrs:{href:"https://diff-store.com/diff/section09__10_jinja_routing",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://diff-store.com/diff/section09__10_jinja_routing"),s("OutboundLink")],1)]),t._v(" "),s("p",[t._v("Note that the code diffs are split into two. One implements a plain menu bar into the app (inside "),s("code",[t._v("/templates")]),t._v("), without using "),s("code",[t._v("url_for")]),t._v(".")]),t._v(" "),s("p",[t._v("The other implements navigation using "),s("code",[t._v("url_for")]),t._v(", and that's in "),s("code",[t._v("templates_urlfor")]),t._v(".")])]),t._v(" "),s("p",[t._v("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.")]),t._v(" "),s("p",[t._v("Let's say we've got these two endpoints in a Flask app:")]),t._v(" "),s("div",{staticClass:"language-py extra-class"},[s("pre",{pre:!0,attrs:{class:"language-py"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" flask "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" redirect"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" url_for\n\napp "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Flask"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("__name__"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\naccount "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("None")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token decorator annotation punctuation"}},[t._v("@app"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("get")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/homepage"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("home")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Home"')]),t._v("\n\n\n"),s("span",{pre:!0,attrs:{class:"token decorator annotation punctuation"}},[t._v("@app"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("get")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/profile"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("profile")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" account"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Profile"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" redirect"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("url_for"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"home"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("Let's assume for a second that the "),s("code",[t._v("account")]),t._v(" variable is what lets us check if the user has logged in or not.")]),t._v(" "),s("p",[t._v("In the second endpoint, if there is an "),s("code",[t._v("account")]),t._v(", then we return \"Profile\". But if there isn't, we'll redirect to the homepage.")]),t._v(" "),s("p",[t._v("Notice that we get the URL to redirect to with the "),s("code",[t._v('url_for("home")')]),t._v(" function. This takes the function name for an endpoint--in this case, the function is called "),s("code",[t._v("home")]),t._v(" and the endpoint is "),s("code",[t._v("/homepage")]),t._v(". It then returns the address to that function's endpoint, in this case, "),s("code",[t._v("/homepage")]),t._v(".")]),t._v(" "),s("p",[t._v("We could just type the string "),s("code",[t._v('"/homepage"')]),t._v(" instead, but this has a few benefits:")]),t._v(" "),s("ul",[s("li",[t._v("It becomes more useful as our apps become more complex.")]),t._v(" "),s("li",[t._v("It works well with blueprints")]),t._v(" "),s("li",[t._v("It means we can change endpoints later on, and as long as we keep the function names the same, our code will still work")]),t._v(" "),s("li",[t._v("It's easy to pass arguments to the endpoint functions without having to think too much about query strings and things like that")])]),t._v(" "),s("p",[t._v("So really in Flask, every time you have a link or a local address, you should be using "),s("code",[t._v("url_for")]),t._v(" instead of hard-coding the URL.")]),t._v(" "),s("h2",{attrs:{id:"code-at-the-start-of-this-lecture"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#code-at-the-start-of-this-lecture"}},[t._v("#")]),t._v(" Code at the start of this lecture")]),t._v(" "),s("p",[t._v("The code is available in the "),s("code",[t._v("start")]),t._v(" folder.")]),t._v(" "),s("p",[t._v("We've got a simple Flask app with a few sample pages:")]),t._v(" "),s("ul",[s("li",[t._v("Home")]),t._v(" "),s("li",[t._v("Login")]),t._v(" "),s("li",[t._v("Signup")])]),t._v(" "),s("p",[t._v("In each page we have a string that tells us what page it is.")]),t._v(" "),s("p",[t._v("In the Login and Signup pages, we also have a link to the other page (to Signup from Login, and to Login from Signup).")]),t._v(" "),s("p",[t._v("The links are using the standard method:")]),t._v(" "),s("div",{staticClass:"language-html extra-class"},[s("pre",{pre:!0,attrs:{class:"language-html"}},[s("code",[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("a")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("href")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("/login"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("Log in instead?"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n")])])]),s("p",[t._v("And there are no links on the homepage.")]),t._v(" "),s("h2",{attrs:{id:"code-written-in-this-lecture"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#code-written-in-this-lecture"}},[t._v("#")]),t._v(" Code written in this lecture")]),t._v(" "),s("p",[t._v("First, let's change the links in the Signup and Login pages to use "),s("code",[t._v("url_for")]),t._v(":")]),t._v(" "),s("p",[t._v("In the Signup page:")]),t._v(" "),s("div",{staticClass:"language-diff extra-class"},[s("pre",{pre:!0,attrs:{class:"language-diff"}},[s("code",[s("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[s("span",{pre:!0,attrs:{class:"token prefix deleted"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token line"}},[t._v('Log in instead?\n')])]),s("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[s("span",{pre:!0,attrs:{class:"token prefix inserted"}},[t._v("+")]),s("span",{pre:!0,attrs:{class:"token line"}},[t._v("Log in instead?\n")])])])])]),s("p",[t._v("And in the Login page:")]),t._v(" "),s("div",{staticClass:"language-diff extra-class"},[s("pre",{pre:!0,attrs:{class:"language-diff"}},[s("code",[s("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[s("span",{pre:!0,attrs:{class:"token prefix deleted"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token line"}},[t._v('Sign up instead?\n')])]),s("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[s("span",{pre:!0,attrs:{class:"token prefix inserted"}},[t._v("+")]),s("span",{pre:!0,attrs:{class:"token line"}},[t._v("Sign up instead?\n")])])])])]),s("p",[t._v("Then, let's also add a navbar to the base page. We could naturally do this using standard links, but we can also use "),s("code",[t._v("url_for")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language-html extra-class"},[s("pre",{pre:!0,attrs:{class:"language-html"}},[s("code",[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("ul")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("navigation"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("li")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("a")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("href")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("{{ url_for("),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("'")]),t._v("home"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("'")]),t._v(") }}"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("Home"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("li")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("a")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("href")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("{{ url_for("),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("'")]),t._v("login"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("'")]),t._v(") }}"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("Log in"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("li")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("a")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("href")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("{{ url_for("),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("'")]),t._v("signup"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("'")]),t._v(") }}"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("Sign up"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n")])])]),s("p",[t._v("Notice that we're using a CSS stylesheet, which is linked in the base page like so:")]),t._v(" "),s("div",{staticClass:"language-html extra-class"},[s("pre",{pre:!0,attrs:{class:"language-html"}},[s("code",[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("link")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("rel")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("stylesheet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("href")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("/static/css/styles.css"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n")])])]),s("p",[t._v("We can also use "),s("code",[t._v("url_for")]),t._v(" here, although the syntax is slightly different:")]),t._v(" "),s("div",{staticClass:"language-html extra-class"},[s("pre",{pre:!0,attrs:{class:"language-html"}},[s("code",[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("link")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("rel")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("stylesheet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("href")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("{{ url_for("),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("'")]),t._v("static"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("'")]),t._v(", filename="),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("'")]),t._v("css/style.css"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("'")]),t._v(") }}"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n")])])]),s("p",[t._v("Instead of passing just the endpoint name, we pass in "),s("code",[t._v("static")]),t._v(". This special name also accepts a "),s("code",[t._v("filename")]),t._v(" argument which tells us which file to load from the "),s("code",[t._v("/static")]),t._v(" URL. The final URL will be "),s("code",[t._v("/static/css/style.css")]),t._v(".")]),t._v(" "),s("h2",{attrs:{id:"final-code-at-the-end-of-this-lecture"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#final-code-at-the-end-of-this-lecture"}},[t._v("#")]),t._v(" Final code at the end of this lecture")]),t._v(" "),s("p",[t._v("This is available in the "),s("code",[t._v("end")]),t._v(" folder.")])])}),[],!1,null,null,null);a.default=n.exports}}]);