Skip to article frontmatterSkip to article content

xxx this chapter is a WIP xxx

there are lots of pieces but all in disorder; the plan is to

I lost Basile’s demo, I’m not sure I need a concrete case for now

xxx WIP xxx


Serving HTML pages

Now that we know how to return JSON, we’ll see how to return HTML
This is of course necessary to offer a user interface
And let’s not forget that HTML itself may require CSS/JS

And make the distinction between


Pages statiques vs dynamiques

Deux cas de figures :


Static vs dynamic pages

Two cases:

“Static” responses
content depending on nothing
so the simplest actually

“Dynamic” responses
content depending on external data

typically:
product search, user profile
obviously the most common case

It’s still useful to make the distinction for performance reasons!
It’s really not useful to solicit a Python stack just to serve a CSS file!

C’est tout de même utile de faire la distinction pour des raisons de performance !
Ce n’est vraiment pas utile de solliciter une stack Python pour juste servir un fichier CSS !


Repo structure

So, this is not imposed by the framework but we usually find a repo structure like this:

./
├── main.py               # FastAPI entrypoint
├── templates/            # Jinja2 (or other) templates
│   ├── base.html
│   └── users/
│       └── profile.html
├── static/               # CSS, JS, images, fonts
└── config.py             # settings

Program 1:Structure usuelle d’un repo FastAPI

from flask import render_template
@app.route("/")
def index():
  return render_template("wheel.html")

However, all files contained in the static folder will be automatically accessible without us having to do anything and that’s 🆒!


Dynamic page: CSR vs SSR

For dynamic pages, two approaches exist

Client Side Rendering

vs

Server Side Rendering


Une démo

xxx no longer working xxx

http://bit.ly/3Tx8wqL

Il faut être curieux et ouvrir l’onglet “Network” des outils de développement du navigateur !


Approche CSR


Approche SSR

Besoin d’un mécanisme de génération de page HTML


Template engine

Mechanism for generating HTML pages from a model and data.

Several technologies/solutions:

Jinja2, Pug, Mustache, Ejs


Jinja 2

Pythonic template engine 🐍

Link with Flask via the render_template function

from flask import render_template

Which we use in routing functions

@app.route("/")
def index():
  context = {}
  ### do something
  return render_template("templated_html.html", **context)

Where context is a Python dictionary containing the variables we want to transmit from our Flask application to the template engine.


Variable substitution

To display the content of a variable in HTML, you need to surround it with double braces in HTML code.

<div>Hello {{ name }}</div>

Conditional blocks

To choose whether to display a part of the HTML page
you can use branches of type {% if %} {% else %} {% endif %}
The syntax is as follows

{% if a_condition %}
<div>some html mess</div>
{% elif another_condition %}
<div>another html jumble</div>
{% else %}
<div>the default html</div>
{% endif %}

Note Python’s None becomes none in Jinja2


For loops

The main interest being dynamic table display.
{% for %} loops in Jinja2 allow you to iterate over any iterable Python object
The syntax is as follows

{% for x in my_list %}
<div>Iteration {{ x }}</div>
{% endfor %}

Dictionary access

if x is itself a dictionary, we can access its keys/values via e.g. x.name or x['name'], the first being generally more convenient

{% for user in users %}
<div>Iteration
  {{ x.name }}
  or also
  {x['age']}
</div>
{% endfor %}

see python/jinja-demo.py for an executable example


Many other things

We’ve skimmed over Jinja’s basic features but there are lots of advanced super practical things

https://jinja.palletsprojects.com/en/3.1.x/templates/

Non-exhaustive list:


CSR vs SSR summary

Two modes with advantages and disadvantages

Roughly

Having pages with lots of interaction,

especially when you’re more into web app than website

speeding up the initial loading of your site, if you have little user interaction,

if you want to optimize your natural search engine ranking.

And from a very pragmatic point of view

may also depend on your comfort level programming in Python or Javascript