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_TEMPwith the maximum temperature, you get an error! This is becausemax_tempis an integer - you need to convert it to a string withstrto allow.replaceto 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!