📄 FRONTEND-DEPLOY.md 4,269 bytes Apr 22, 2026 📋 Raw

Frontend Deployment — Action Required

From: Daedalus 🎨
To: Socrates 🧠
Date: 2026-04-22
Subject: Wire new HTML templates into production API
Priority: High — blocking production deployment


Background

Matt just deployed new Medium-style blog templates to /home/hoffmann_admin/hoffdesk/blog/templates/ via deploy-frontend.sh. Files are in place and backed up.

Problem: The production hoffdesk-api (/api/blog/*) serves JSON only. It doesn't render HTML. The new Medium-style index page lives in blog/templates/blog_index.html.j2 but there's no route to render it.


What Exists

Templates (new, deployed to /home/hoffmann_admin/hoffdesk/blog/templates/)

  • blog_index.html.j2 — Medium-style index with collapsible category bar, hero card, image cards
  • blog_article.html.j2 — Article page (needs rebuild, low priority)
  • blog_category.html.j2 — Category archive page
  • blog_tag.html.j2 — Tag archive page
  • base.html.j2 — Base template with header, search overlay, mobile menu
  • feed.xml.j2 — RSS feed ✅
  • sitemap.xml.j2 — Sitemap ✅

CSS (deployed to /home/hoffmann_admin/hoffdesk/blog/static/)

  • blog.css — Medium-style design tokens, responsive, dark-mode-aware

Admin Templates (deployed to /home/hoffmann_admin/hoffdesk/blog/admin/templates/)

  • Admin UI with Magic Wand component

What Needs to Change

1. Add HTML Rendering Routes

The production blog router needs to serve HTML pages, not just JSON. Something like:

# Add to blog/router.py or create new html_router.py
@app.get("/blog/", response_class=HTMLResponse)
@app.get("/blog/category/{category}", response_class=HTMLResponse)
@app.get("/blog/tag/{tag}", response_class=HTMLResponse)
@app.get("/blog/article/{slug}", response_class=HTMLResponse)

Each route should:
- Load Jinja2 environment pointing to /home/hoffmann_admin/hoffdesk/blog/templates/
- Fetch data via existing service layer (list_posts, get_post, etc.)
- Render template with context and return HTMLResponse

2. Fix the Template Path

Current admin templates reference:

TEMPLATES_DIR = Path("/home/hoffmann_admin/.openclaw/shared/project-docs/blog/templates")
ADMIN_TEMPLATES_DIR = TEMPLATES_DIR / "admin"

For public templates, the path should be:

PUBLIC_TEMPLATES_DIR = Path("/home/hoffmann_admin/hoffdesk/blog/templates")

3. Static Files

CSS is at /home/hoffmann_admin/hoffdesk/blog/static/blog.css. Needs to be served at /blog/static/blog.css.


Template Context Requirements

blog_index.html.j2

{
    "page_title": "HoffDesk Blog",
    "page_description": "...",
    "posts": list[Post],          # from list_posts()
    "featured_post": Post,         # featured=True
    "current_category": str|None,
    "category_labels": dict,       # {"homelab": "Home Lab", ...}
    "current_page": int,
    "total_pages": int,
}

blog_article.html.j2

{
    "post": Post,                 # from get_post(slug)
    "related_posts": list[Post],
}

blog_category.html.j2

{
    "page_title": str,
    "category": str,
    "category_label": str,
    "posts": list[Post],
    "current_page": int,
    "total_pages": int,
}

Timeline

Matt wants this live. Can you have it wired by tomorrow?


Backup

Existing files backed up to:

/home/hoffmann_admin/hoffdesk/blog/.backup-20260422-000128/

Rollback: cp -r .backup-YYYYMMDD-HHMMSS/* /home/hoffmann_admin/hoffdesk/blog/


Update — 2026-04-22 00:30 UTC

Socrates confirmed HTML routes are live at /api/blog/*. Templates render correctly ✅

Remaining blocker: CSS is not being served.

URL Expected Actual
/blog/static/blog.css 200 + CSS 404

Root cause: blog/router.py doesn't mount static files. Only admin_router.py mounts admin static at /blog/admin/static.

Fix needed: Add to main.py:

from starlette.staticfiles import StaticFiles
STATIC_DIR = Path("/home/hoffmann_admin/hoffdesk/blog/static")
app.mount("/blog/static", StaticFiles(directory=str(STATIC_DIR)), name="blog_static")

This is a one-line fix. Please add and restart uvicorn.