When I was just starting out with Python Flask, I found it pretty confusing to pass make my HTML communicate with my backend. This article hopes to explain this as simply as possible.

File Structure

Let's keep things simple, and deal with only 2 files — app.py and templates/index.html.

templates/index.html
app.py

The Code

The code inside app.py

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def home():
    fruits = ['apple', 'orange', 'pear', 'pineapple', 'durian']
    return render_template(
        'index.html',
        name='bob',
        age=40, 
        fruits=fruits
    )

if __name__ == '__main__':
    app.run()

The code inside index.html

<div>
    Name: {{name}}
</div>

<div>
    Age: {{age}}
</div>

<br><br>

{% for fruit in fruits %}
    <div>{{fruit}}</div>
{% endfor %}

What's Happening

Normally, when I use the render_template function in Python flask, I simply do something like return render_template('index.html').

However, notice that we have additional keyword arguments behind the 'index.html' argument.

return render_template(
      'index.html',
      name='bob',
      age=40, 
      fruits=fruits
  )

These keyword arguments are responsible for passing data from our backend to our HTML frontend. More examples:

return render_template(
      'index.html',
      name='bob'
  )

# only the variable 'name' (with a value 'bob') is passed to our frontend
return render_template(
      'index.html',
      age=40
  )

# only the variable 'age' (with a value 40) is passed to our frontend
return render_template(
      'index.html',
      name='bob',
      age=40
  )

# both variables name='bob' and age=40 are passed to our frontend.

How Our HTML Frontend Handles This

Note — this works in Python Flask because of the jinja2 library.

<div>
    Name: {{name}}
</div>

<div>
    Age: {{age}}
</div>

<br><br>

{% for fruit in fruits %}
    <div>{{fruit}}</div>
{% endfor %}

Notice the name and age inside double curly brackets eg. {{name}}. This is the way to pass a simple variable to our HTML frontend.

As for fruits, which is a list, we use a for loop to display all fruits. Notice the odd {% for fruit in fruits %} and {% endfor %} syntax. This is possible because of jinja2.

We then put double curly brackets around fruit, which also happens to be the iterator variable in {% for fruit in fruits %}. Which allows us to be able to display each individual fruit.

Some Final words

If this story provided value to you, and you wish to show support, you could:

  1. Clap multiple times for this story (this really helps me out!)
  2. Consider signing up for a Medium membership using my link — it's $5 per month and you get to read unlimited stories on Medium.

Sign up using my link here to read unlimited Medium articles.

Get my free Ebooks: https://zlliu.co/books

I write Python articles (sometimes other stuff) that the younger me would have wanted to read. Do join my email list to get notified whenever I publish.

More content at PlainEnglish.io. Sign up for our free weekly newsletter. Follow us on Twitter, LinkedIn, YouTube, and Discord.

Interested in scaling your software startup? Check out Circuit.