Skip to main content

Templates


Learning Objectives#

After this lesson, you will be able to:

  • Create a template HTML document.
  • Pass variables to a template HTML document via a Flask app.

A Million Copies#

  • Don't you hate it when you have to repeat yourself?

  • What if you had a website with 10 pages that were almost the same?

  • Would you code them all from scratch?


We Do: Your index.html Page#

  • Any route can use an html page.

  • Try it!

    • In your my_website.py, set the /randnum/<inte> and / routes to both render_template("index.html").
  • What if we want them to display a different heading?

  • Do we need to rewrite the whole file?


No! That's What Templates Are For#

Teaching Tip:

  • Talk for a few minutes here about design patterns and why it's important to split data from presentation.

We use templates to:

  • Write one HTML file.
  • Pass it variables.
  • Transfer info from Flask to HTML.

As well as for one important design reason:

  • We can separate data from how we present data to users.

Jinja2#

  • One of the most widely used template engines for Python.
  • Used in places that you might have visited already, like Instagram or NPR.

Why Jinja2?#

Talking Points:

  • Jinja2 is kind of like the engine that powers our vehicle (Flask). However, this happens behind the scenes.

  • We're quickly peering behind the scenes to get an idea of what our engine can do.

  • Some examples of what makes Jinja2 awesome are:

    • Template inheritance: You can extend templates in very efficient ways.
    • HTML escaping: Malicious hackers can create XSS attacks by injecting HTML code into our site where other users insert data. Jinja2 helps us avoid that.
    • Speed and efficiency: Jinja2 is very fast. It compiles optimized Python code.
    • Flexibility and extensibility: It's really easy to add our own filters and functions.

Jinja2 has some really powerful features that web design folks want to take advantage of:

  • Template inheritance
    • Like class inheritance!
  • HTML escaping
    • Stops some hacking attacks (XSS and SQL injection).
  • Speed and efficiency
    • Optimized Python code.
  • Flexibility and extensibility
    • We can add our own filters and functions.

Knowledge Check: Discussion#

  • What's one reason why we might want to use templates, other than staying DRY?

Talking Point:

  • Answer: Templates allow us to add programming languages to our HTML templates.

  • What's template inheritance?

Talking Point:

  • Template inheritance is extending templates in very efficient ways.

Expanding on Our index.html#

  • We'll send a greeting variable into our index.html from both routes.

  • The routes will display different things!


Adding Templates#

Talking Points:

  • This is the function that Flask uses to… you guessed it: Render our template(s)!

  • For this exercise, we want to add some programming language (Python) into our HTML template.

  • Remember import render_template?

  • This is the function that Flask uses to… you guessed it: Render our template(s)!


Edit index.html#

  • Change the <h1> to be {{ greeting }}.
...   <body>      <h1>Hello {{ name }}!</h1>   <p>If music be the food of love, play on!</p> ....

Templating Syntax With Jinja#

Talking Points:

  • What's awesome about this is that inside of these brackets, we can pass in Python syntax.

  • In our example, we have a variable, which we're calling name.

  • Whatever we assign to the variable name will be rendered when our page renders.

  • Statements are where we would pass in logic like {%if this thing%} {% else that thing%}.

  • Recognize the {{}}?

  • In Jinja, templates are rendered with double curly brackets ({{ }}).

  • Statements are rendered with curly brackets and percent signs ({% %}).

    • A use case here is passing in logic like:
 {% if name == 'kevin' %} # Do the thing {% else %} # Do all the other things.

Rendering a Template in Flask#

Talking Points:

  • We're going to modify the rest of our Flask app to pass some values into our variable in the template (curly braces).

  • Let's change the rest of our hello_flask.py so that the whole thing looks the following script on screen.

  • Here, we use render_template function which takes in two arguments:

    1. Our template name, index.html.
    2. Our context which, from the documentation is "the variables that should be available in the context of the template."
  • Here, our variable is name which is passed into the user part of our route, and then becomes the value that we assign to the variable called name.

Let's change our my_website.py accordingly:

@app.route('/')def home():  return render_template("index.html", greeting="Hello World!")
...
@app.route('/shownum/<inte>')def shownum(inte):  my_greeting = "Your number is " + str(inte)  return render_template("index.html", greeting=my_greeting)

Try it#

  • Check out: http://localhost:5000.
  • Then: http://localhost:5000/shownum/26.

Do your other routes still work?


Knowledge Check: Discussion#

What two arguments did we pass into the render_template function?

Talking Point:

  • Answer: index.html, our template name, and greeting, which is our context.

What's one reason we use templates?

Talking Points:

Possible answers:

  • Adding programming languages to our HTML templates.
  • Transferring info from Flask to HTML.
  • Lets us separate data from how we present data to users.

Your Turn#

  • Create a new Flask app, shakespeare.py.
  • Create a new template HTML file, hello.html.
    • It will display a paragraph with a parameter poem in it.
  • Render it from the index endpoint.
  • Remember calling in variables from the last lesson?
    • Have your Flask app read in the poem saved in hi.txt, then pass that to the hello.html template to display.
  • Launch your Flask app and check the results!

Template Solution#

<!doctype html><html><head>    <meta charset="utf-8">    <title>Shakespeare</title></head><body>    <p>{{text}}</p></body></html>

Python Solution#

from flask import Flask, render_templateimport os # Note the new import — to be in the file system.
app = Flask(__name__)
file_path = '.'
with open(os.path.join(file_path, 'hi.txt')) as f: the_text = f.read()
@app.route('/') # When someone goes here...def home(): # Do this.    return render_template("hello.html", text=the_text)
if __name__ == '__main__': app.run(debug=True)

Summary#

  • Jinja:

    • A popular templating engine.
    • Templates save us time and abstract presentation from data.
  • Template fun:

    • We can pass variables into the template from the Flask app and the URL.