Add Flask admin API and live preview endpoint

This commit is contained in:
Walter Jekat 2025-12-05 11:44:43 +01:00
parent 68bf11a54e
commit 5b38054273
1 changed files with 87 additions and 0 deletions

87
admin_app.py Normal file
View File

@ -0,0 +1,87 @@
import yaml
from flask import Flask, jsonify, request, Response, abort
import build # reuse your existing static builder logic
app = Flask(__name__)
def list_pages():
"""
Return a lightweight list of pages for a sidebar etc.
Uses build.load_pages() from the existing builder.
"""
pages = build.load_pages()
result = []
for p in pages:
result.append({
"slug": p.get("slug", ""),
"title": p.get("title", ""),
"language": p.get("language", "de"),
})
result.sort(key=lambda x: x["slug"])
return result
@app.get("/api/pages")
def api_list_pages():
return jsonify(list_pages())
@app.get("/api/pages/<slug>")
def api_get_page(slug):
try:
page, path = build.load_page_by_slug(slug)
except FileNotFoundError:
abort(404, description="Page not found")
return jsonify(page)
@app.put("/api/pages/<slug>")
def api_save_page(slug):
"""
Save page JSON back as YAML. For now we trust the structure,
since the admin UI is under our control.
"""
try:
_, path = build.load_page_by_slug(slug)
except FileNotFoundError:
abort(404, description="Page not found")
new_page = request.get_json(force=True, silent=False)
if not isinstance(new_page, dict):
abort(400, description="Expected JSON object")
# Ensure slug consistency
new_page.setdefault("slug", slug)
with open(path, "w", encoding="utf-8") as f:
yaml.safe_dump(
new_page,
f,
allow_unicode=True,
sort_keys=False,
width=1000,
)
return ("", 204)
@app.get("/preview/<slug>/")
def preview_page(slug):
"""
Render HTML for a single page using existing Jinja templates.
No disk write: we render directly from the current YAML content.
"""
try:
page, _ = build.load_page_by_slug(slug)
except FileNotFoundError:
abort(404, description="Page not found")
html = build.render_page(page)
return Response(html, mimetype="text/html")
if __name__ == "__main__":
# For development; in production we'll run this with gunicorn and Caddy as reverse proxy.
app.run(host="127.0.0.1", port=8075, debug=True)