Simple HTML templates with Python¶
Sometimes when you're building a website with HTML, you want something on the page to update. Maybe you want to write a new date every time you republish, maybe you want to insert some values from a CSV, maybe you want to just do anything dynamic.
The fanciest way to do this involves running a server that constantly runs code for you – Python or node.js or PHP or whatever – and delivers a new page every time a user visits it. Running a server is a real pain, though, so we're going to go with an alternative of a template-based static site.
A template-based static site needs two things:
- An HTML template with some "please replace me" sections
- You running some Python code to replace the values
And that's it!! Let's go through the process step by step.
Note: If you want to do this the "real" way you should just a templating engine like Jinja. The simple technique below takes about 10% of the effort with 90% of the results, though, so maybe don't look at Jinja unless you want something very fancy (or want to learn a new tool!).
Your HTML template¶
First, you'll want to build your entire web page, but put something obnoxious and variable-y as placeholders where you want your content.
In this example, we're building a website that does something with weather. It will look like this:
We've saved it as template.html
, and when we read it in using Python it looks like this:
html = open("template.html").read()
print(html)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>My website</title> <style> body { font-family: Arial, Helvetica, sans-serif; background: aliceblue; } .container { max-width: 700px; margin: auto; } </style> </head> <body> <div class="container"> <h1>🌤️ Today is INSERT_TIME</h1> <p>We have INSERT_ROWS rows in the database. The highest temperature is INSERT_MAX_TEMP.</p> </div> </body> </html>
On our page we have three placeholders:
INSERT_TIME
: the time we updated the pageINSERT_ROWS
: the number of rows in our datasetINSERT_MAX_TEMP
: the maximum temperature in our dataset
They don't have to be capitalized! They don't have to start with INSERT_
! They can be whatever you want! You could have called them $%$%POTATOBUGS#*@&
if you want, doesn't matter.
Using Python to replace values¶
We have a template with placeholders, but what do we want in those places? We can get the data from anywhere - functions, APIs, CSV files... In this case, we're getting the values from datetime
and a CSV file.
We'll start by getting the number of rows and the maximum temperature.
import pandas as pd
import datetime
df = pd.read_csv("temps.csv")
df.head()
city | temp | |
---|---|---|
0 | Paris | 17 |
1 | London | 15 |
2 | Cairo | 25 |
num_rows = df.shape[0]
max_temp = df.temp.max()
print(num_rows)
print(max_temp)
3 25
Then we can use the datetime
library to get the current date. We'll use strftime to format it to look nice.
current_date = datetime.datetime.now().strftime("%B %d, %Y")
current_date
'December 10, 2023'
Now we read in our template.html
file...
html = open("template.html").read()
print(html)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>My website</title> <style> body { font-family: Arial, Helvetica, sans-serif; background: aliceblue; } .container { max-width: 700px; margin: auto; } </style> </head> <body> <div class="container"> <h1>🌤️ Today is INSERT_TIME</h1> <p>We have INSERT_ROWS rows in the database. The highest temperature is INSERT_MAX_TEMP.</p> </div> </body> </html>
...and just use .replace
to replace all of our placeholders with the values that we want to fill in.
Note: If you try to replace
INSERT_MAX_TEMP
with the maximum temperature, you get an error! This is becausemax_temp
is an integer - you need to convert it to a string withstr
to allow.replace
to work okay.
html = html.replace("INSERT_TIME", current_date)
html = html.replace("INSERT_ROWS", str(num_rows))
html = html.replace("INSERT_MAX_TEMP", str(max_temp))
print(html)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>My website</title> <style> body { font-family: Arial, Helvetica, sans-serif; background: aliceblue; } .container { max-width: 700px; margin: auto; } </style> </head> <body> <div class="container"> <h1>🌤️ Today is December 10, 2023</h1> <p>We have 3 rows in the database. The highest temperature is 25.</p> </div> </body> </html>
Now that our HTML looks good we can save it. Make sure to save it as index.html
so you don't replace your old template.html
!
with open("index.html", "w") as fp:
fp.write(html)
And now we can open it and see the beauty of our filled-in webpage!
Note that we saved it as index.html
, when we publish the site back to the internet it will automatically show up!