Fix page editing: use Ghost /pages/ API for pages, not /posts/
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 56s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 56s
Ghost has separate /posts/ and /pages/ endpoints. All admin functions (get_post_for_edit, update_post, update_post_settings, sync) were hardcoded to /posts/, causing 404s when editing pages. Now checks is_page from post_data and uses the correct endpoint. Also uses sync_single_page (not sync_single_post) after page saves to prevent IntegrityError from mismatched fetch/upsert paths. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -30,10 +30,11 @@ def _check(resp: httpx.Response) -> None:
|
||||
resp.raise_for_status()
|
||||
|
||||
|
||||
async def get_post_for_edit(ghost_id: str) -> dict | None:
|
||||
"""Fetch a single post by Ghost ID, including lexical source."""
|
||||
async def get_post_for_edit(ghost_id: str, *, is_page: bool = False) -> dict | None:
|
||||
"""Fetch a single post/page by Ghost ID, including lexical source."""
|
||||
resource = "pages" if is_page else "posts"
|
||||
url = (
|
||||
f"{GHOST_ADMIN_API_URL}/posts/{ghost_id}/"
|
||||
f"{GHOST_ADMIN_API_URL}/{resource}/{ghost_id}/"
|
||||
"?formats=lexical,html,mobiledoc&include=newsletters"
|
||||
)
|
||||
async with httpx.AsyncClient(timeout=30) as client:
|
||||
@@ -41,7 +42,7 @@ async def get_post_for_edit(ghost_id: str) -> dict | None:
|
||||
if resp.status_code == 404:
|
||||
return None
|
||||
_check(resp)
|
||||
return resp.json()["posts"][0]
|
||||
return resp.json()[resource][0]
|
||||
|
||||
|
||||
async def create_post(
|
||||
@@ -114,6 +115,7 @@ async def update_post(
|
||||
newsletter_slug: str | None = None,
|
||||
email_segment: str | None = None,
|
||||
email_only: bool | None = None,
|
||||
is_page: bool = False,
|
||||
) -> dict:
|
||||
"""Update an existing Ghost post. Returns the updated post dict.
|
||||
|
||||
@@ -141,9 +143,10 @@ async def update_post(
|
||||
post_body["status"] = status
|
||||
if email_only:
|
||||
post_body["email_only"] = True
|
||||
payload = {"posts": [post_body]}
|
||||
resource = "pages" if is_page else "posts"
|
||||
payload = {resource: [post_body]}
|
||||
|
||||
url = f"{GHOST_ADMIN_API_URL}/posts/{ghost_id}/"
|
||||
url = f"{GHOST_ADMIN_API_URL}/{resource}/{ghost_id}/"
|
||||
if newsletter_slug:
|
||||
url += f"?newsletter={newsletter_slug}"
|
||||
if email_segment:
|
||||
@@ -151,7 +154,7 @@ async def update_post(
|
||||
async with httpx.AsyncClient(timeout=30) as client:
|
||||
resp = await client.put(url, json=payload, headers=_auth_header())
|
||||
_check(resp)
|
||||
return resp.json()["posts"][0]
|
||||
return resp.json()[resource][0]
|
||||
|
||||
|
||||
_SETTINGS_FIELDS = (
|
||||
@@ -178,22 +181,24 @@ _SETTINGS_FIELDS = (
|
||||
async def update_post_settings(
|
||||
ghost_id: str,
|
||||
updated_at: str,
|
||||
is_page: bool = False,
|
||||
**kwargs,
|
||||
) -> dict:
|
||||
"""Update Ghost post settings (slug, tags, SEO, social, etc.).
|
||||
"""Update Ghost post/page settings (slug, tags, SEO, social, etc.).
|
||||
|
||||
Only non-None keyword args are included in the PUT payload.
|
||||
Accepts any key from ``_SETTINGS_FIELDS``.
|
||||
"""
|
||||
resource = "pages" if is_page else "posts"
|
||||
post_body: dict = {"updated_at": updated_at}
|
||||
for key in _SETTINGS_FIELDS:
|
||||
val = kwargs.get(key)
|
||||
if val is not None:
|
||||
post_body[key] = val
|
||||
|
||||
payload = {"posts": [post_body]}
|
||||
url = f"{GHOST_ADMIN_API_URL}/posts/{ghost_id}/"
|
||||
payload = {resource: [post_body]}
|
||||
url = f"{GHOST_ADMIN_API_URL}/{resource}/{ghost_id}/"
|
||||
async with httpx.AsyncClient(timeout=30) as client:
|
||||
resp = await client.put(url, json=payload, headers=_auth_header())
|
||||
_check(resp)
|
||||
return resp.json()["posts"][0]
|
||||
return resp.json()[resource][0]
|
||||
|
||||
Reference in New Issue
Block a user