Phase 1 — Section-based store homepages:
- Store defaults use template="full" with per-platform sections JSON
- OMS: shop hero + features + CTA; Loyalty: rewards hero + features + CTA
- Hosting: services hero + features + CTA
- Deep placeholder resolution for {{store_name}} inside sections JSON
- landing-full.html uses resolved page_sections from context
Phase 2 — Module-contributed header actions:
- header_template field on MenuItemDefinition + DiscoveredMenuItem
- Catalog provides header-search.html partial
- Cart provides header-cart.html partial with badge
- Base template iterates storefront_nav.actions with {% include %}
- Generic icon fallback for actions without a template
Fixes:
- Store theme API: get_store_by_code → get_store_by_code_or_subdomain
Docs:
- CMS redesign proposal: menu restructure, page types, translations UI
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
11 KiB
Proposal: CMS Redesign — Alignment with Market Standards
Date: 2026-04-14 Status: Draft Author: Samir / Claude
Problem Statement
The CMS has good foundations but several design flaws that create confusion and limit usability:
- Template vs Theme are disconnected — Theme (colors/fonts at
/admin/stores/{code}/theme) and page template (layout structure inContentPage.template) are separate concepts with overlapping names, no UI connection - No template selector in admin — The
templatefield can only be set via seed data or API, not the UI - Content vs Sections duality — A page has both a freeform
contentfield AND a structuredsectionsJSON. Which one renders depends on the template. Confusing for admins - Sections editor shows platform-only sections — Pricing section appears for store pages where it makes no sense
- No title/content translation UI — The
title_translationsandcontent_translationsfields exist in the model but have no admin editor. Only seed data populates them. Store overrides lose translations - Fixed section types — Only 5-8 section types, can't be extended by modules
- No section reordering — Sections render in a fixed order defined by the template
- Everything mixed in one list — Platform marketing pages, store defaults, and store overrides all in
/admin/content-pages
Specific bug found
FASHIONHUB has a store override for /about with title_translations=NULL. The override was created without translations (no UI to add them), so it always shows "About Fashion Hub" regardless of language. The store default it overrides has full translations (fr="À propos", etc.).
Market Standard (Shopify, WordPress, Squarespace)
| Concept | Market Standard | Our Current State |
|---|---|---|
| Page types | "Page" (prose) vs "Landing page" (sections) — clearly distinct | Mixed: same model, hidden template field decides rendering |
| Template | A starting point you choose when creating a page, pre-populates layout | Hidden field, can't be changed in UI |
| Sections | Ordered list, drag-and-drop, add/remove any type | Fixed positions, hardcoded in template |
| Theme | Global visual styling (colors, fonts) applied to all templates | Separate system, works but disconnected |
| Translations | Per-field translations, always visible when editing | Fields exist but no admin UI for page title/content |
| Content editing | Rich text for prose pages, section editor for landing pages | Both shown on same edit page |
| Storefront management | Dedicated section (Shopify: "Online Store") | Mixed into Content Management |
Proposed Admin Menu Restructure
Current
Content Management (CMS module, order=70)
├── Content Pages → /admin/content-pages (everything mixed)
└── Store Themes → /admin/store-themes
Platform Admin (Tenancy module)
├── Merchants → /admin/merchants
├── Stores → /admin/stores
└── Platforms → /admin/platforms
Proposed
Platform Admin (Tenancy module)
├── Merchants → /admin/merchants
├── Stores → /admin/stores
├── Storefronts → /admin/storefronts ← NEW (card grid per store)
└── Platforms → /admin/platforms
Content Management (CMS module)
├── Platform Pages → /admin/platform-pages (renamed, platform marketing only)
└── Media Library → /admin/media
Storefronts page (/admin/storefronts)
Card grid layout (like current /admin/store-themes but expanded). Each store card shows:
┌─────────────────────────────────────┐
│ 🏪 FashionHub │
│ loyalty platform · active │
│ │
│ [Customize Theme] [Edit Homepage] │
│ [Manage Pages] [Preview →] │
└─────────────────────────────────────┘
| Action | What it opens |
|---|---|
| Customize Theme | /admin/stores/{code}/theme (existing, works well) |
| Edit Homepage | Landing page section editor for this store's slug=home page |
| Manage Pages | List of content pages for this store (about, contact, faq — with translations) |
| Preview | Opens storefront in new tab |
This replaces the current Store Themes menu item — themes become one tab/action within the broader Storefronts management.
Platform Pages (/admin/platform-pages)
Renamed from "Content Pages". Only shows is_platform_page=True pages. Used for platform marketing (homepage, pricing, about, terms, privacy). This is what the admin uses to manage the platform marketing site — not individual store content.
Proposed CMS Changes
Change 1: Page type selector in admin UI
Add a Page Type dropdown at the top of the content page edit form:
| Page Type | Template field | Editor shows | Hides |
|---|---|---|---|
| Content Page | default |
Title (with translations), content editor (with translations), SEO | Sections editor |
| Landing Page | full |
Title (with translations), section editor, SEO | Content field |
When switching types:
- Content → Landing: initialize empty sections if none exist, hide content field
- Landing → Content: show content field, hide sections editor
- Data is preserved in both cases (no deletion)
Change 2: Title and content translation UI
Add language tabs to the title and content fields — same pattern the sections editor already uses:
[FR] [EN] [DE] [LB]
┌────────────────────────────┐
│ Title: À propos │
└────────────────────────────┘
┌────────────────────────────┐
│ Content: │
│ Bienvenue chez ... │
└────────────────────────────┘
- Default language tab edits
form.title/form.contentdirectly - 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
Hide irrelevant sections based on page context:
| 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 |
Implementation: pass is_platform_page to the JS component, conditionally show Pricing.
Change 4: Sections as ordered list (future)
Current: Dict with fixed keys ({"hero": {...}, "features": {...}, "cta": {...}})
Proposed: Ordered array:
[
{"type": "hero", "enabled": true, "data": {...}},
{"type": "features", "enabled": true, "data": {...}},
{"type": "cta", "enabled": true, "data": {...}}
]
Benefits:
- Admin can reorder (drag-and-drop)
- Admin can add/remove section types
- Template iterates array generically
- New section types don't require template changes
Migration: if sections is a dict → render in legacy order. If array → render in order.
Change 5: Module-contributed section types (future)
New contract: StorefrontSectionProviderProtocol
- Catalog contributes:
product-showcase,category-grid - Loyalty contributes:
loyalty-signup,rewards-overview - Section registry aggregates from enabled modules
- Admin section editor shows available types from enabled modules
What Stays the Same
- 3-tier content hierarchy (platform → store default → store override) — solid
- TranslatableText pattern for sections — well-built
- Section partials as Jinja2 macros — reusable, themeable
- Module-driven menus and widgets — clean contracts
- Theme system (colors, fonts, CSS variables) — works well
- CMS context providers for header/footer pages — good pattern
- ContentPage model — no schema changes needed for Phase A
Implementation Phases
Phase A: Quick fixes (immediate, no schema changes)
- 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
- Fix: FASHIONHUB about page — add translations
- Fix: store theme API bug (done —
get_store_by_code_or_subdomain)
Phase B: Menu restructure + Storefronts page
- Add "Storefronts" menu item under Platform Admin
- Build card grid page at
/admin/storefronts - Rename "Content Pages" → "Platform Pages" (filter to
is_platform_page=True) - Move Store Themes into Storefronts
- "Edit Homepage" action on store card → section editor for store's home page
- "Manage Pages" action → filtered content page list for that store
Phase C: Section ordering + add/remove
- Migrate sections from dict to ordered array
- Drag-and-drop reordering in admin section editor
- Add/remove sections from available types
- Template renders sections from ordered array
- Backward compatibility for dict-format sections
Phase D: Module-contributed sections
StorefrontSectionProviderProtocolcontract- Catalog: product-showcase section
- Loyalty: loyalty-signup section
- Section registry in CMS module
- Admin section editor shows available types from enabled modules
Relation to Storefront Builder Vision
This proposal covers the CMS foundation. The broader storefront builder vision builds on top:
| Builder Vision Phase | CMS Redesign Phase |
|---|---|
| Phase 1: Wire sections to store homepages | ✅ Done |
| Phase 2: Module header actions | ✅ Done |
| Phase 3: Module-contributed sections | Phase D |
| Phase 4: Widget slots | Separate (post Phase D) |
| Phase 5: Per-store menus | Phase B sets up the UI |
| Phase 6: Visual editor | Post Phase C (drag-and-drop foundation) |
Key Files
| Component | File |
|---|---|
| Content page edit template | app/modules/cms/templates/cms/admin/content-page-edit.html |
| Content page edit JS | app/modules/cms/static/admin/js/content-page-edit.js |
| ContentPage model | app/modules/cms/models/content_page.py |
| Section schemas | app/modules/cms/schemas/homepage_sections.py |
| Section partials | app/modules/cms/templates/cms/platform/sections/_*.html |
| CMS definition (admin menu) | app/modules/cms/definition.py |
| Tenancy definition (admin menu) | app/modules/tenancy/definition.py |
| Store theme page | app/modules/tenancy/templates/tenancy/admin/store-theme.html |
| Store themes list | app/modules/cms/templates/cms/admin/store-themes.html |
| Storefront landing templates | app/modules/cms/templates/cms/storefront/landing-*.html |
| Seed data | scripts/seed/create_default_content_pages.py |