feat: implement Pages as Spaces Phase 1
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 45s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 45s
- Add PageConfig model with feature flags (calendar, market) - Auto-create PageConfig on Ghost page sync - Add create_page() for Ghost /pages/ API endpoint - Add /new-page/ route for creating pages - Add ?type=pages blog filter with Posts|Pages tab toggle - Add list_pages() to DBClient with PageConfig eager loading - Add PUT /<slug>/admin/features/ route for feature toggles - Add feature badges (calendar, market) on page cards - Add features panel to page admin dashboard - Update shared_lib submodule with PageConfig model Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -73,6 +73,35 @@ async def create_post(
|
||||
return resp.json()["posts"][0]
|
||||
|
||||
|
||||
async def create_page(
|
||||
title: str,
|
||||
lexical_json: str,
|
||||
status: str = "draft",
|
||||
feature_image: str | None = None,
|
||||
custom_excerpt: str | None = None,
|
||||
feature_image_caption: str | None = None,
|
||||
) -> dict:
|
||||
"""Create a new page in Ghost (via /pages/ endpoint). Returns the created page dict."""
|
||||
page_body: dict = {
|
||||
"title": title,
|
||||
"lexical": lexical_json,
|
||||
"mobiledoc": None,
|
||||
"status": status,
|
||||
}
|
||||
if feature_image:
|
||||
page_body["feature_image"] = feature_image
|
||||
if custom_excerpt:
|
||||
page_body["custom_excerpt"] = custom_excerpt
|
||||
if feature_image_caption is not None:
|
||||
page_body["feature_image_caption"] = feature_image_caption
|
||||
payload = {"pages": [page_body]}
|
||||
url = f"{GHOST_ADMIN_API_URL}/pages/"
|
||||
async with httpx.AsyncClient(timeout=30) as client:
|
||||
resp = await client.post(url, json=payload, headers=_auth_header())
|
||||
_check(resp)
|
||||
return resp.json()["pages"][0]
|
||||
|
||||
|
||||
async def update_post(
|
||||
ghost_id: str,
|
||||
lexical_json: str,
|
||||
|
||||
@@ -13,6 +13,7 @@ from sqlalchemy.orm.attributes import flag_modified # for non-Mutable JSON colu
|
||||
from models.ghost_content import (
|
||||
Post, Author, Tag, PostAuthor, PostTag
|
||||
)
|
||||
from models.page_config import PageConfig
|
||||
|
||||
# User-centric membership models
|
||||
from models import User
|
||||
@@ -238,6 +239,15 @@ async def _upsert_post(sess: AsyncSession, gp: Dict[str, Any], author_map: Dict[
|
||||
tt = tag_map[t["id"]]
|
||||
sess.add(PostTag(post_id=obj.id, tag_id=tt.id, sort_order=idx))
|
||||
|
||||
# Auto-create PageConfig for pages
|
||||
if obj.is_page:
|
||||
existing_pc = (await sess.execute(
|
||||
select(PageConfig).where(PageConfig.post_id == obj.id)
|
||||
)).scalar_one_or_none()
|
||||
if existing_pc is None:
|
||||
sess.add(PageConfig(post_id=obj.id, features={}))
|
||||
await sess.flush()
|
||||
|
||||
return obj
|
||||
|
||||
async def _ghost_find_member_by_email(email: str) -> Optional[dict]:
|
||||
|
||||
Reference in New Issue
Block a user