Project 15: Email HTML Renderer ✉️¶
Difficulty: 🟡 Intermediate
Run cells top to bottom. Each step builds on the previous one and saves real files under outputs/email_html_renderer/.
Description¶
Use Jinja2 templates to render beautiful HTML emails from data — the backbone of newsletters and notifications.
Libraries & Modules¶
jinja2—Template,Environment- Built-in:
json,Path
Python Concepts You'll Practice¶
Template engines, variable substitution, HTML generation
🎛️ Parameter Variations¶
USER_NAME,CTA_URL,CTA_TEXTTHEME_PRIMARY,THEME_BG— brand colors- Edit the HTML template structure for layout changes
In [1]:
# Install dependencies for this project (safe to re-run)
import sys
!{sys.executable} -m pip install pillow numpy matplotlib wordcloud qrcode[pil] python-barcode fpdf2 jinja2 folium plotly pandas scipy ipywidgets -q
Skipping pip install (already installed)
In [2]:
# Interactive Jupyter setup — run this cell first
%matplotlib inline
from pathlib import Path
from IPython.display import display, Image as IPImage, HTML, Markdown, Audio, IFrame
OUTPUT_DIR = Path("outputs") / "email_html_renderer"
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
print(f"✅ Outputs folder: {OUTPUT_DIR.resolve()}")
✅ Outputs folder: C:\Users\Hansel Yan\Projects\CodeItAll\outputs\email_html_renderer
Step 1 — Define template & context¶
In [3]:
from jinja2 import Template
# 🎛️ TWEAK THESE
USER_NAME = "Sam"
CTA_URL = "https://codeitall.dev/start"
CTA_TEXT = "Continue Learning"
THEME_PRIMARY = "#6c5ce7"
THEME_BG = "#f8f9fa"
HEADLINE = "Your weekly Python progress is here!"
TEMPLATE = """
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>CodeItAll</title></head>
<body style="margin:0;font-family:Arial,sans-serif;background:{{ theme_bg }};">
<table width="100%" cellpadding="0" cellspacing="0">
<tr><td align="center" style="padding:40px 20px;">
<table width="600" style="background:#fff;border-radius:12px;overflow:hidden;box-shadow:0 4px 20px rgba(0,0,0,0.08);">
<tr><td style="background:{{ theme_primary }};padding:30px;text-align:center;">
<h1 style="color:#fff;margin:0;">CodeItAll</h1>
</td></tr>
<tr><td style="padding:30px;">
<p>Hi <strong>{{ user_name }}</strong>,</p>
<h2 style="color:{{ theme_primary }};">{{ headline }}</h2>
<p>You completed <strong>{{ lessons_done }}</strong> lessons this week. Keep going!</p>
<p style="text-align:center;margin-top:30px;">
<a href="{{ cta_url }}" style="background:{{ theme_primary }};color:#fff;padding:14px 28px;text-decoration:none;border-radius:8px;font-weight:bold;">{{ cta_text }}</a>
</p>
</td></tr>
</table>
</td></tr>
</table>
</body>
</html>
"""
context = dict(
user_name=USER_NAME,
headline=HEADLINE,
lessons_done=7,
cta_url=CTA_URL,
cta_text=CTA_TEXT,
theme_primary=THEME_PRIMARY,
theme_bg=THEME_BG,
)
html = Template(TEMPLATE).render(**context)
print(html[:400] + "...")
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>CodeItAll</title></head>
<body style="margin:0;font-family:Arial,sans-serif;background:#f8f9fa;">
<table width="100%" cellpadding="0" cellspacing="0">
<tr><td align="center" style="padding:40px 20px;">
<table width="600" style="background:#fff;border-radius:12px;overflow:hidden;box-shadow:0 4px 20px rgba(0,0,0,0.08);">
...
Step 2 — Save HTML (open in browser)¶
In [4]:
out = OUTPUT_DIR / "email_preview.html"
out.write_text(html, encoding="utf-8")
print(f"Open in browser: {out.resolve()}")
Open in browser: C:\Users\Hansel Yan\Projects\CodeItAll\outputs\email_html_renderer\email_preview.html