# 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: ```python # 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` ```python { "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` ```python { "post": Post, # from get_post(slug) "related_posts": list[Post], } ``` ### `blog_category.html.j2` ```python { "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`: ```python 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.