feat(cms): Phase A — page type selector, translation UI, SEO cleanup
Some checks failed
CI / ruff (push) Successful in 16s
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / pytest (push) Has been cancelled

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:
2026-04-16 22:30:55 +02:00
parent bb3d6f0012
commit b5bb9415f6
11 changed files with 293 additions and 91 deletions

View File

@@ -129,21 +129,16 @@ Add **language tabs** to the title and content fields — same pattern the secti
- Other language tabs edit `form.title_translations[lang]` / `form.content_translations[lang]`
- When creating a store override from a default, pre-populate translations from the default
### Change 3: Context-aware section editor
### Change 3: Template-driven section palette
Hide irrelevant sections based on page context:
The **template** (page type) defines which sections are available — not a hardcoded list filtered by context. The admin section editor loads the available section types from a template config.
| Section | Platform Homepage | Store Homepage |
|---------|------------------|----------------|
| Hero | Yes | Yes |
| Features | Yes | Yes |
| Pricing | Yes | **No** |
| CTA | Yes | Yes |
| Testimonials | Yes | Yes |
| Gallery | Yes | Yes |
| Contact Info | Yes | Yes |
| Template | Available Sections |
|----------|-------------------|
| `default` (platform homepage) | hero, features, products, pricing, testimonials, gallery, contact_info, cta |
| `full` (store landing page) | hero, features, testimonials, gallery, contact_info, cta |
Implementation: pass `is_platform_page` to the JS component, conditionally show Pricing.
Implementation: a `TEMPLATE_SECTION_PALETTE` dict mapping template name → list of allowed section types. The route handler passes the palette to the editor JS, which only renders sections in the palette. This keeps the logic in one place and sets up Phase C/D — when sections become an ordered array with add/remove, the template defines the palette of available types, and modules can extend that palette.
### Change 4: Sections as ordered list (future)
@@ -193,7 +188,7 @@ New contract: `StorefrontSectionProviderProtocol`
- [ ] Title + content translation UI (language tabs on edit page)
- [ ] Page type selector (Content Page / Landing Page dropdown)
- [ ] Hide content field when Landing Page selected
- [ ] Hide Pricing section for non-platform pages
- [ ] Template-driven section palette (template defines which sections are available)
- [ ] Fix: FASHIONHUB about page — add translations
- [ ] Fix: store theme API bug (done — `get_store_by_code_or_subdomain`)