Wire sx_content through full read/write pipeline

Model: add sx_content column to Post. Writer: accept sx_content in
create_post, create_page, update_post. Routes: read sx_content from form
data in new post, new page, and edit routes. Read pipeline: ghost_db
includes sx_content in public dict, detail/home views prefer sx_content
over html when available, PostDTO includes sx_content.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-01 23:22:30 +00:00
parent 341fc4cf28
commit 7ccb463a8b
9 changed files with 34 additions and 6 deletions

View File

@@ -19,6 +19,7 @@ def _post_to_dto(post: Post) -> PostDTO:
is_page=post.is_page,
feature_image=post.feature_image,
html=post.html,
sx_content=post.sx_content,
excerpt=post.excerpt,
custom_excerpt=post.custom_excerpt,
published_at=post.published_at,

View File

@@ -207,6 +207,7 @@ async def create_post(
feature_image_caption: str | None = None,
tag_names: list[str] | None = None,
is_page: bool = False,
sx_content: str | None = None,
) -> Post:
"""Create a new post or page directly in db_blog."""
html, plaintext, reading_time = _render_and_extract(lexical_json)
@@ -217,6 +218,7 @@ async def create_post(
title=title or "Untitled",
slug=slug,
lexical=lexical_json if isinstance(lexical_json, str) else json.dumps(lexical_json),
sx_content=sx_content,
html=html,
plaintext=plaintext,
reading_time=reading_time,
@@ -281,6 +283,7 @@ async def create_page(
custom_excerpt: str | None = None,
feature_image_caption: str | None = None,
tag_names: list[str] | None = None,
sx_content: str | None = None,
) -> Post:
"""Create a new page. Convenience wrapper around create_post."""
return await create_post(
@@ -294,6 +297,7 @@ async def create_page(
feature_image_caption=feature_image_caption,
tag_names=tag_names,
is_page=True,
sx_content=sx_content,
)
@@ -308,6 +312,7 @@ async def update_post(
custom_excerpt: str | None = ..., # type: ignore[assignment]
feature_image_caption: str | None = ..., # type: ignore[assignment]
status: str | None = None,
sx_content: str | None = ..., # type: ignore[assignment]
) -> Post:
"""Update post content. Optimistic lock via expected_updated_at.
@@ -342,6 +347,9 @@ async def update_post(
if title is not None:
post.title = title
if sx_content is not _SENTINEL:
post.sx_content = sx_content
if feature_image is not _SENTINEL:
post.feature_image = feature_image
if custom_excerpt is not _SENTINEL: