Add Page
This commit is contained in:
50
main.py
50
main.py
@@ -254,7 +254,7 @@ def api_create_page(slug: str) -> tuple[Response, int]:
|
||||
|
||||
@app.route("/api/save", methods=["POST"]) # type: ignore[untyped-decorator]
|
||||
def api_save() -> tuple[Response, int] | Response:
|
||||
"""接受 vvvebjs 的儲存請求,寫入對應專案目錄."""
|
||||
"""接受 vvvebjs 的儲存或新增頁面請求,寫入對應專案目錄."""
|
||||
if request.is_json:
|
||||
raw: dict[str, Any] = request.get_json(force=True) or {}
|
||||
body: dict[str, Any] = raw
|
||||
@@ -263,15 +263,52 @@ def api_save() -> tuple[Response, int] | Response:
|
||||
body = {k: (v[0] if isinstance(v, list) else v) for k, v in form.items()}
|
||||
|
||||
slug: str = str(body.get("slug", "")).strip()
|
||||
filename: str = str(body.get("file", "")).strip()
|
||||
html: str = str(body.get("html", "")).strip()
|
||||
|
||||
if not slug or not filename or not html:
|
||||
return jsonify({"error": "缺少必要參數 slug / file / html"}), 400
|
||||
if not slug:
|
||||
return jsonify({"error": "缺少專案識別碼 (slug)"}), 400
|
||||
|
||||
if not _project_dir(slug).exists():
|
||||
return jsonify({"error": "專案不存在"}), 404
|
||||
|
||||
# 1. 判斷是否為新增頁面請求 (含有 startTemplateUrl)
|
||||
start_template_url = str(body.get("startTemplateUrl", "")).strip()
|
||||
if start_template_url:
|
||||
title = str(body.get("title", "")).strip() or "New Page"
|
||||
# 取得安全的檔名 (只取檔名部分,例如 'about.html')
|
||||
filename = Path(str(body.get("file", "untitled.html")).strip()).name
|
||||
if not filename.endswith(".html"):
|
||||
filename += ".html"
|
||||
|
||||
safe_path = _sanitize_file_path(slug, filename)
|
||||
if safe_path is None:
|
||||
return jsonify({"error": "不合法的頁面名稱"}), 400
|
||||
|
||||
if safe_path.exists():
|
||||
return jsonify({"error": "頁面已存在"}), 409
|
||||
|
||||
# 解析並複製樣板 (定位在 static/Vvvebjs 目錄下)
|
||||
template_source = BASE_DIR / "static" / "Vvvebjs" / start_template_url
|
||||
if template_source.exists() and template_source.is_file():
|
||||
shutil.copy(template_source, safe_path)
|
||||
else:
|
||||
_copy_blank_template(safe_path)
|
||||
|
||||
# 回傳 VvvebJS FileManager 所期待的 JSON 格式
|
||||
page_name = safe_path.stem
|
||||
return jsonify({
|
||||
"ok": True,
|
||||
"name": page_name,
|
||||
"title": title,
|
||||
"file": safe_path.name,
|
||||
"url": f"/sites/{slug}/{safe_path.name}"
|
||||
})
|
||||
|
||||
# 2. 一般儲存頁面請求
|
||||
filename = str(body.get("file", "")).strip()
|
||||
html: str = str(body.get("html", "")).strip()
|
||||
|
||||
if not filename or not html:
|
||||
return jsonify({"error": "缺少必要參數 file / html"}), 400
|
||||
|
||||
safe_path = _sanitize_file_path(slug, filename)
|
||||
if safe_path is None:
|
||||
return jsonify({"error": "不合法的檔案路徑"}), 400
|
||||
@@ -280,6 +317,7 @@ def api_save() -> tuple[Response, int] | Response:
|
||||
return jsonify({"ok": True, "saved": safe_path.name})
|
||||
|
||||
|
||||
|
||||
@app.route("/sites/<slug>/<path:filename>") # type: ignore[untyped-decorator]
|
||||
def serve_site_file(slug: str, filename: str) -> Response:
|
||||
proj_dir = _project_dir(slug)
|
||||
|
||||
Reference in New Issue
Block a user