club-builder/build.py

125 lines
3.7 KiB
Python

import os
import datetime
import shutil
import yaml
import markdown
from jinja2 import Environment, FileSystemLoader, select_autoescape
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
CONTENT_PAGES_DIR = os.path.join(BASE_DIR, "content", "de", "pages")
STATIC_SRC = os.path.join(BASE_DIR, "static")
TEMPLATES_DIR = os.path.join(BASE_DIR, "templates")
DIST_BASE = os.path.join(os.path.dirname(BASE_DIR), "builds", "preview")
env = Environment(
loader=FileSystemLoader(TEMPLATES_DIR),
autoescape=select_autoescape(["html", "xml"]),
)
def load_pages():
pages = []
for filename in os.listdir(CONTENT_PAGES_DIR):
if not filename.endswith(".yaml"):
continue
path = os.path.join(CONTENT_PAGES_DIR, filename)
with open(path, "r", encoding="utf-8") as f:
data = yaml.safe_load(f)
pages.append(data)
return pages
def load_page_by_slug(slug):
"""
Load a single page dict and its file path by slug.
Assumes each YAML file in CONTENT_PAGES_DIR has a 'slug' field.
"""
for filename in os.listdir(CONTENT_PAGES_DIR):
if not filename.endswith(".yaml"):
continue
path = os.path.join(CONTENT_PAGES_DIR, filename)
with open(path, "r", encoding="utf-8") as f:
data = yaml.safe_load(f)
if data and data.get("slug") == slug:
return data, path
raise FileNotFoundError(f"No page with slug={slug!r} in {CONTENT_PAGES_DIR}")
def render_page(page):
template_name = "page.html" # all use same template for now
template = env.get_template(template_name)
# Process blocks and render markdown for prose
blocks = []
for b in page.get("blocks", []):
block = dict(b) # shallow copy
# Markdown rendering for prose blocks: overwrite `content` with HTML
if block.get("type") == "prose" and "content" in block:
block["content"] = markdown.markdown(
block["content"],
extensions=["extra", "sane_lists"]
)
# Markdown rendering for card_grid card texts
if block.get("type") == "card_grid" and "cards" in block:
new_cards = []
for c in block["cards"]:
card = dict(c)
if "text" in card:
card["text"] = markdown.markdown(
card["text"],
extensions=["extra", "sane_lists"]
)
new_cards.append(card)
block["cards"] = new_cards
blocks.append(block)
html = template.render(
page=page, # NEW: pass whole page object
title=page.get("title", ""),
language=page.get("language", "de"),
blocks=blocks,
current_year=datetime.date.today().year,
)
return html
def write_page(page, html):
slug = page.get("slug", "index")
# For now, every page goes to /slug/index.html
out_dir = os.path.join(DIST_BASE, slug)
os.makedirs(out_dir, exist_ok=True)
out_path = os.path.join(out_dir, "index.html")
with open(out_path, "w", encoding="utf-8") as f:
f.write(html)
print(f"Wrote {out_path}")
def copy_static():
if not os.path.isdir(STATIC_SRC):
print(f"No static dir at {STATIC_SRC}, skipping.")
return
static_dst = os.path.join(DIST_BASE, "static")
if os.path.exists(static_dst):
shutil.rmtree(static_dst)
shutil.copytree(STATIC_SRC, static_dst)
print(f"Copied static assets to {static_dst}")
def main():
os.makedirs(DIST_BASE, exist_ok=True)
pages = load_pages()
for page in pages:
html = render_page(page)
write_page(page, html)
copy_static()
if __name__ == "__main__":
main()