feat(storefront): section-based homepages, header action partials, fixes
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>
This commit is contained in:
253
docs/proposals/cms-redesign-alignment.md
Normal file
253
docs/proposals/cms-redesign-alignment.md
Normal file
@@ -0,0 +1,253 @@
|
||||
# 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:
|
||||
|
||||
1. **Template vs Theme are disconnected** — Theme (colors/fonts at `/admin/stores/{code}/theme`) and page template (layout structure in `ContentPage.template`) are separate concepts with overlapping names, no UI connection
|
||||
2. **No template selector in admin** — The `template` field can only be set via seed data or API, not the UI
|
||||
3. **Content vs Sections duality** — A page has both a freeform `content` field AND a structured `sections` JSON. Which one renders depends on the template. Confusing for admins
|
||||
4. **Sections editor shows platform-only sections** — Pricing section appears for store pages where it makes no sense
|
||||
5. **No title/content translation UI** — The `title_translations` and `content_translations` fields exist in the model but have no admin editor. Only seed data populates them. Store overrides lose translations
|
||||
6. **Fixed section types** — Only 5-8 section types, can't be extended by modules
|
||||
7. **No section reordering** — Sections render in a fixed order defined by the template
|
||||
8. **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.content` directly
|
||||
- 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:
|
||||
```json
|
||||
[
|
||||
{"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
|
||||
- [ ] `StorefrontSectionProviderProtocol` contract
|
||||
- [ ] 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](storefront-builder-vision.md) 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` |
|
||||
Reference in New Issue
Block a user