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/.

← Back to index

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_TEXT
  • THEME_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

✅ Project complete¶

Check your output folder: outputs/email_html_renderer/

Next: Project 16: Stock Sparkline Dashboard · Index