feat(storefront): homepage, module gating, widget protocol, i18n fixes
Some checks failed
Some checks failed
Storefront homepage & module gating:
- CMS owns storefront GET / (slug="home" with 3-tier resolution)
- Catalog loses GET / (keeps /products only)
- Store root redirect (GET / → /store/dashboard or /store/login)
- Route gating: non-core modules return 404 when disabled for platform
- Seed store default homepages per platform
Widget protocol for customer dashboard:
- StorefrontDashboardCard contract in widgets.py
- Widget aggregator get_storefront_dashboard_cards()
- Orders and Loyalty module widget providers
- Dashboard template renders contributed cards (no module names)
Landing template module-agnostic:
- CTAs driven by storefront_nav (not hardcoded module names)
- Header actions check nav item IDs (not enabled_modules)
- Remove hardcoded "Add Product" sidebar button
- Remove all enabled_modules checks from storefront templates
i18n fixes:
- Title placeholder resolution ({{store_name}}) for store default pages
- Storefront nav label_keys prefixed with module code
- Add storefront.account.* keys to 6 modules (en/fr/de/lb)
- Header/footer CMS pages use get_translated_title(current_language)
- Footer labels use i18n keys instead of hardcoded English
Icon cleanup:
- Standardize on map-pin (remove location-marker alias)
- Replace all location-marker references across templates and docs
Docs:
- Storefront builder vision proposal (6 phases)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
256
docs/proposals/storefront-builder-vision.md
Normal file
256
docs/proposals/storefront-builder-vision.md
Normal file
@@ -0,0 +1,256 @@
|
||||
# Proposal: Storefront Builder Vision
|
||||
|
||||
**Date:** 2026-04-13
|
||||
**Status:** Draft
|
||||
**Author:** Samir / Claude
|
||||
|
||||
---
|
||||
|
||||
## Problem Statement
|
||||
|
||||
The platform has a solid CMS foundation — section-based homepages, module-driven menus, widget contracts, theme system, 3-tier content hierarchy, multi-language support. However, there are gaps between the platform marketing site (well-built) and the store storefront (catching up). The goal is to enable "yes, we can build you a one-page ecommerce site" as a real capability.
|
||||
|
||||
---
|
||||
|
||||
## Current State
|
||||
|
||||
### What works well
|
||||
- **Platform homepage**: Section-based rendering via `page.sections` JSON with 8 section partials (hero, features, pricing, CTA, testimonials, gallery, contact, products)
|
||||
- **Admin section editor**: API for editing sections individually or all at once, multi-language
|
||||
- **Module contracts**: Widget protocol, context providers, menu declarations, route gating
|
||||
- **Store theme**: Colors, fonts, logo, custom CSS — all applied via CSS variables
|
||||
- **Component library**: Ecommerce macros (product cards, grids, add-to-cart, mini-cart) at `/admin/components#ecommerce`
|
||||
- **3-tier content**: Platform pages → store defaults → store overrides, with placeholder resolution
|
||||
|
||||
### What's missing
|
||||
1. Store homepages don't use sections (only `landing-full.html` supports them, but defaults use `landing-default.html`)
|
||||
2. Header actions (search, cart) are bespoke in the base template
|
||||
3. No widget slots on storefront pages (widgets only on dashboards)
|
||||
4. No per-store menu customization (menus are platform-wide)
|
||||
5. Section types are fixed (8 types, not pluggable by modules)
|
||||
6. No visual editor (admin edits via JSON-backed forms)
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Wire Sections to Store Homepages
|
||||
|
||||
**Goal:** Store homepages get section-based rendering immediately, using existing infrastructure.
|
||||
|
||||
### Changes
|
||||
- Change seed script: store default homepages use `template="full"` instead of `template="default"`
|
||||
- Populate `sections` JSON per platform:
|
||||
- **OMS stores**: Hero → Product Showcase → Features → CTA
|
||||
- **Loyalty stores**: Hero → Loyalty Signup → Features → CTA
|
||||
- **Hosting stores**: Hero → Services → Features → CTA
|
||||
- Admin can already edit sections via existing API at `/admin/content-pages/{id}/edit`
|
||||
|
||||
### Impact
|
||||
- Every store immediately gets a section-based homepage
|
||||
- Merchants can customize via admin UI (no code changes needed)
|
||||
- All 8 existing section types available
|
||||
|
||||
### Effort
|
||||
Small — mostly seed data and one template field change.
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Module-Contributed Header Actions
|
||||
|
||||
**Goal:** Remove bespoke header rendering. Modules provide their own action templates.
|
||||
|
||||
### Changes
|
||||
- Add optional `header_template` field to `MenuItemDefinition` in `app/modules/base.py`
|
||||
- Cart module provides `cart/storefront/partials/header-cart.html` (cart icon + Alpine badge)
|
||||
- Catalog module provides `catalog/storefront/partials/header-search.html` (search button + modal trigger)
|
||||
- Update `storefront/base.html`: iterate `storefront_nav.get('actions', [])`, use `{% include item.header_template %}` when present, generic link otherwise
|
||||
- Remove all hardcoded action rendering from base template
|
||||
|
||||
### Architecture
|
||||
```
|
||||
Module definition:
|
||||
MenuItemDefinition(
|
||||
id="cart",
|
||||
label_key="cart.storefront.actions.cart",
|
||||
icon="shopping-cart",
|
||||
route="cart",
|
||||
header_template="cart/storefront/partials/header-cart.html",
|
||||
)
|
||||
|
||||
Base template:
|
||||
{% for item in storefront_nav.get('actions', []) %}
|
||||
{% if item.header_template %}
|
||||
{% include item.header_template %}
|
||||
{% else %}
|
||||
<a href="{{ base_url }}{{ item.route }}">{{ _(item.label_key) }}</a>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
### Impact
|
||||
- Any module can contribute a header action with custom UI
|
||||
- Adding wishlist, notifications, etc. requires zero base template changes
|
||||
- Fully module-agnostic
|
||||
|
||||
### Effort
|
||||
Small — new field on MenuItemDefinition, two partial templates, base template update.
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: Module-Contributed Page Sections
|
||||
|
||||
**Goal:** Modules can register their own section types for storefront pages.
|
||||
|
||||
### Changes
|
||||
- New contract: `StorefrontSectionProviderProtocol` in `app/modules/contracts/`
|
||||
```python
|
||||
class StorefrontSectionProviderProtocol(Protocol):
|
||||
def get_section_types(self) -> list[SectionTypeDefinition]: ...
|
||||
# SectionTypeDefinition: id, name, icon, template_path, default_config
|
||||
```
|
||||
- New field on `ModuleDefinition`: `section_provider`
|
||||
- Section registry in CMS module aggregates section types from all enabled modules
|
||||
- Catalog contributes:
|
||||
- `product-showcase` — featured products grid (uses existing product card macros)
|
||||
- `category-grid` — browse by category
|
||||
- Loyalty contributes:
|
||||
- `loyalty-signup` — join rewards CTA with program details
|
||||
- `rewards-overview` — points/stamps explanation
|
||||
- Update admin section editor to show available sections from enabled modules
|
||||
|
||||
### Architecture
|
||||
```
|
||||
Section rendering flow:
|
||||
1. Page has sections JSON: {"hero": {...}, "product-showcase": {...}, ...}
|
||||
2. Template iterates sections in order
|
||||
3. For each section, looks up the partial from the section registry
|
||||
4. Renders: {% include section_registry[section_type].template_path %}
|
||||
5. Passes section data + language context
|
||||
```
|
||||
|
||||
### Impact
|
||||
- Platform-specific storefronts: OMS stores get product sections, Loyalty stores get loyalty sections
|
||||
- Admin editor adapts to available sections based on platform modules
|
||||
- No template changes needed when adding new section types
|
||||
|
||||
### Effort
|
||||
Medium — new contract, section registry service, admin UI update, 4-6 new section partials.
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: Storefront Page Widget Slots
|
||||
|
||||
**Goal:** Place smaller components within pages — product carousels, loyalty badges, social feeds.
|
||||
|
||||
### Changes
|
||||
- Define named slots in storefront templates: `below-hero`, `above-footer`, `content-sidebar`
|
||||
- New contract method on widget protocol:
|
||||
```python
|
||||
def get_page_widgets(self, db, store_id, slot, page_slug, context) -> list[StorefrontPageWidget]
|
||||
# StorefrontPageWidget: key, template, data, order
|
||||
```
|
||||
- Widget aggregator collects from enabled modules per slot
|
||||
- Templates render:
|
||||
```jinja
|
||||
{% for widget in page_widgets.get('below-hero', []) %}
|
||||
{% include widget.template %}
|
||||
{% endfor %}
|
||||
```
|
||||
- Catalog contributes: "featured products" widget, "new arrivals" widget
|
||||
- Loyalty contributes: "join rewards" widget, "points balance" widget
|
||||
|
||||
### Sections vs Widgets
|
||||
- **Sections** = full-width page blocks, ordered top-to-bottom, part of page structure
|
||||
- **Widgets** = smaller components placed within named slots, multiple per slot
|
||||
|
||||
### Impact
|
||||
- Mix-and-match content: a loyalty store can add a product widget to their homepage
|
||||
- Modules contribute without coupling — templates never check module names
|
||||
- Foundation for "one-page ecommerce" capability
|
||||
|
||||
### Effort
|
||||
Medium — builds on existing widget infrastructure, new slot rendering in templates.
|
||||
|
||||
---
|
||||
|
||||
## Phase 5: Per-Store Menu & Section Ordering
|
||||
|
||||
**Goal:** Stores can customize their navigation and homepage layout.
|
||||
|
||||
### Changes
|
||||
- **Menu overrides**: `store_menu_config` table (store_id, item_id, is_visible, display_order)
|
||||
- Stores can hide/reorder items from the platform menu
|
||||
- menu_discovery_service gets a store-level filter on top of platform-level
|
||||
- **Section ordering**: `display_order` field per section in the `sections` JSON
|
||||
- Admin UI: drag-and-drop section reordering
|
||||
- Sections can be enabled/disabled per store override
|
||||
- **Section visibility**: Store overrides can hide sections from the default homepage
|
||||
|
||||
### Impact
|
||||
- Each store can have a unique navigation and homepage layout
|
||||
- Platform provides the base, stores customize
|
||||
- Follows existing 3-tier pattern (platform → store default → store override)
|
||||
|
||||
### Effort
|
||||
Medium-large — new table, menu service update, admin drag-and-drop UI.
|
||||
|
||||
---
|
||||
|
||||
## Phase 6: Visual Editor (Future)
|
||||
|
||||
**Goal:** WYSIWYG editing experience for storefront pages.
|
||||
|
||||
### Changes
|
||||
- Live preview panel showing section rendering as you edit
|
||||
- Drag-and-drop section placement and reordering
|
||||
- Inline text editing with rich text toolbar
|
||||
- Template/section picker with visual thumbnails
|
||||
- Mobile/desktop preview toggle
|
||||
|
||||
### Architecture
|
||||
- Frontend-only addition — calls the same section APIs
|
||||
- Could use iframe-based preview with postMessage communication
|
||||
- Section partials render identically in preview and production
|
||||
|
||||
### Impact
|
||||
- Non-technical merchants can build their own storefronts
|
||||
- Reduces support burden
|
||||
- Competitive feature for attracting merchants
|
||||
|
||||
### Effort
|
||||
Large — significant frontend work, but backend APIs already exist.
|
||||
|
||||
---
|
||||
|
||||
## One-Page Ecommerce Site — End-to-End Flow
|
||||
|
||||
With Phases 1-4 complete, here's the workflow:
|
||||
|
||||
1. **Admin creates store** on OMS platform
|
||||
2. **Store homepage** auto-created with section-based default (hero, product showcase, features, CTA)
|
||||
3. **Merchant edits** at `/admin/content-pages/{id}/edit`:
|
||||
- Hero: store branding, tagline, "Shop Now" button
|
||||
- Product Showcase: featured products (from catalog module section)
|
||||
- Testimonials: customer reviews
|
||||
- CTA: newsletter signup
|
||||
4. **Theme** at `/admin/stores/{code}/theme`: colors, logo, fonts
|
||||
5. **Customer visits** storefront → sees professional one-page site with products, cart, checkout
|
||||
|
||||
---
|
||||
|
||||
## Key Files Reference
|
||||
|
||||
| Component | File |
|
||||
|-----------|------|
|
||||
| Section partials | `app/modules/cms/templates/cms/platform/sections/_*.html` |
|
||||
| ContentPage model | `app/modules/cms/models/content_page.py` |
|
||||
| Section schemas | `app/modules/cms/schemas/homepage_sections.py` |
|
||||
| Widget contracts | `app/modules/contracts/widgets.py` |
|
||||
| Module base | `app/modules/base.py` (MenuItemDefinition, ModuleDefinition) |
|
||||
| Storefront base | `app/templates/storefront/base.html` |
|
||||
| Store theme model | `app/modules/cms/models/store_theme.py` |
|
||||
| Menu discovery | `app/modules/core/services/menu_discovery_service.py` |
|
||||
| Widget aggregator | `app/modules/core/services/widget_aggregator.py` |
|
||||
| Component library | `app/modules/dev_tools/templates/dev_tools/admin/components.html` |
|
||||
| Seed data | `scripts/seed/create_default_content_pages.py` |
|
||||
| Storefront routes | `app/modules/cms/routes/pages/storefront.py` |
|
||||
| Admin section API | `app/modules/cms/routes/api/admin_content_pages.py` |
|
||||
Reference in New Issue
Block a user