feat(cms): Phase A — page type selector, translation UI, SEO cleanup
Some checks failed
Some checks failed
Content page editor improvements: - Page type selector: Content Page / Landing Page dropdown (sets template) - Title language tabs: translate page titles per language (same pattern as sections) - Content language tabs: translate page content per language - Meta description language tabs: translatable SEO descriptions - Template-driven section palette: template defines which sections are available (store landing pages hide Pricing, platform homepages show all) - Hide content editor when Landing Page selected, hide sections when Content Page Schema changes (migration cms_003): - Add meta_description_translations column (JSON) to content_pages - Drop meta_keywords column (obsolete, ignored by all search engines since 2009) - Remove meta keywords tag from storefront and platform base templates API + service updates: - title_translations, content_translations, meta_description_translations added to create/update schemas, route handlers, and service methods Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -473,7 +473,7 @@ class ContentPageService:
|
||||
content_format: str = "html",
|
||||
template: str = "default",
|
||||
meta_description: str | None = None,
|
||||
meta_keywords: str | None = None,
|
||||
meta_description_translations: str | None = None,
|
||||
is_published: bool = False,
|
||||
show_in_footer: bool = True,
|
||||
show_in_header: bool = False,
|
||||
@@ -495,7 +495,7 @@ class ContentPageService:
|
||||
content_format: "html" or "markdown"
|
||||
template: Template name for landing pages
|
||||
meta_description: SEO description
|
||||
meta_keywords: SEO keywords
|
||||
meta_description_translations: Meta description translations dict
|
||||
is_published: Publish immediately
|
||||
show_in_footer: Show in footer navigation
|
||||
show_in_header: Show in header navigation
|
||||
@@ -516,7 +516,7 @@ class ContentPageService:
|
||||
content_format=content_format,
|
||||
template=template,
|
||||
meta_description=meta_description,
|
||||
meta_keywords=meta_keywords,
|
||||
meta_description_translations=meta_description_translations,
|
||||
is_published=is_published,
|
||||
published_at=datetime.now(UTC) if is_published else None,
|
||||
show_in_footer=show_in_footer,
|
||||
@@ -542,11 +542,13 @@ class ContentPageService:
|
||||
db: Session,
|
||||
page_id: int,
|
||||
title: str | None = None,
|
||||
title_translations: dict[str, str] | None = None,
|
||||
content: str | None = None,
|
||||
content_translations: dict[str, str] | None = None,
|
||||
content_format: str | None = None,
|
||||
template: str | None = None,
|
||||
meta_description: str | None = None,
|
||||
meta_keywords: str | None = None,
|
||||
meta_description_translations: str | None = None,
|
||||
is_published: bool | None = None,
|
||||
show_in_footer: bool | None = None,
|
||||
show_in_header: bool | None = None,
|
||||
@@ -574,16 +576,20 @@ class ContentPageService:
|
||||
# Update fields if provided
|
||||
if title is not None:
|
||||
page.title = title
|
||||
if title_translations is not None:
|
||||
page.title_translations = title_translations
|
||||
if content is not None:
|
||||
page.content = content
|
||||
if content_translations is not None:
|
||||
page.content_translations = content_translations
|
||||
if content_format is not None:
|
||||
page.content_format = content_format
|
||||
if template is not None:
|
||||
page.template = template
|
||||
if meta_description is not None:
|
||||
page.meta_description = meta_description
|
||||
if meta_keywords is not None:
|
||||
page.meta_keywords = meta_keywords
|
||||
if meta_description_translations is not None:
|
||||
page.meta_description_translations = meta_description_translations
|
||||
if is_published is not None:
|
||||
page.is_published = is_published
|
||||
if is_published and not page.published_at:
|
||||
@@ -699,7 +705,7 @@ class ContentPageService:
|
||||
content: str | None = None,
|
||||
content_format: str | None = None,
|
||||
meta_description: str | None = None,
|
||||
meta_keywords: str | None = None,
|
||||
meta_description_translations: str | None = None,
|
||||
is_published: bool | None = None,
|
||||
show_in_footer: bool | None = None,
|
||||
show_in_header: bool | None = None,
|
||||
@@ -726,7 +732,7 @@ class ContentPageService:
|
||||
content=content,
|
||||
content_format=content_format,
|
||||
meta_description=meta_description,
|
||||
meta_keywords=meta_keywords,
|
||||
meta_description_translations=meta_description_translations,
|
||||
is_published=is_published,
|
||||
show_in_footer=show_in_footer,
|
||||
show_in_header=show_in_header,
|
||||
@@ -761,7 +767,7 @@ class ContentPageService:
|
||||
content: str,
|
||||
content_format: str = "html",
|
||||
meta_description: str | None = None,
|
||||
meta_keywords: str | None = None,
|
||||
meta_description_translations: str | None = None,
|
||||
is_published: bool = False,
|
||||
show_in_footer: bool = True,
|
||||
show_in_header: bool = False,
|
||||
@@ -792,7 +798,7 @@ class ContentPageService:
|
||||
is_platform_page=False,
|
||||
content_format=content_format,
|
||||
meta_description=meta_description,
|
||||
meta_keywords=meta_keywords,
|
||||
meta_description_translations=meta_description_translations,
|
||||
is_published=is_published,
|
||||
show_in_footer=show_in_footer,
|
||||
show_in_header=show_in_header,
|
||||
@@ -914,11 +920,13 @@ class ContentPageService:
|
||||
db: Session,
|
||||
page_id: int,
|
||||
title: str | None = None,
|
||||
title_translations: dict[str, str] | None = None,
|
||||
content: str | None = None,
|
||||
content_translations: dict[str, str] | None = None,
|
||||
content_format: str | None = None,
|
||||
template: str | None = None,
|
||||
meta_description: str | None = None,
|
||||
meta_keywords: str | None = None,
|
||||
meta_description_translations: str | None = None,
|
||||
is_published: bool | None = None,
|
||||
show_in_footer: bool | None = None,
|
||||
show_in_header: bool | None = None,
|
||||
@@ -936,11 +944,13 @@ class ContentPageService:
|
||||
db,
|
||||
page_id=page_id,
|
||||
title=title,
|
||||
title_translations=title_translations,
|
||||
content=content,
|
||||
content_translations=content_translations,
|
||||
content_format=content_format,
|
||||
template=template,
|
||||
meta_description=meta_description,
|
||||
meta_keywords=meta_keywords,
|
||||
meta_description_translations=meta_description_translations,
|
||||
is_published=is_published,
|
||||
show_in_footer=show_in_footer,
|
||||
show_in_header=show_in_header,
|
||||
|
||||
Reference in New Issue
Block a user