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:
@@ -28,6 +28,71 @@ ROUTE_CONFIG = {
|
||||
}
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# STOREFRONT HOMEPAGE
|
||||
# ============================================================================
|
||||
|
||||
|
||||
@router.get("/", response_class=HTMLResponse, include_in_schema=False)
|
||||
async def storefront_homepage(
|
||||
request: Request,
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Storefront homepage handler.
|
||||
|
||||
Looks for a CMS page with slug="home" (store override → store default),
|
||||
and renders the appropriate landing template. Falls back to the default
|
||||
landing template when no CMS homepage exists.
|
||||
"""
|
||||
store = getattr(request.state, "store", None)
|
||||
platform = getattr(request.state, "platform", None)
|
||||
store_id = store.id if store else None
|
||||
if not platform:
|
||||
raise HTTPException(status_code=400, detail="Platform context required")
|
||||
|
||||
# Try to load a homepage from CMS (store override → store default)
|
||||
page = content_page_service.get_page_for_store(
|
||||
db,
|
||||
platform_id=platform.id,
|
||||
slug="home",
|
||||
store_id=store_id,
|
||||
include_unpublished=False,
|
||||
)
|
||||
|
||||
# Resolve placeholders for store default pages (title + content)
|
||||
page_content = None
|
||||
page_title = None
|
||||
if page:
|
||||
page_content = page.content
|
||||
page_title = page.title
|
||||
if page.is_store_default and store:
|
||||
page_content = content_page_service.resolve_placeholders(
|
||||
page.content, store
|
||||
)
|
||||
page_title = content_page_service.resolve_placeholders(
|
||||
page.title, store
|
||||
)
|
||||
|
||||
context = get_storefront_context(request, db=db, page=page)
|
||||
if page_content:
|
||||
context["page_content"] = page_content
|
||||
if page_title:
|
||||
context["page_title"] = page_title
|
||||
|
||||
# Select template based on page.template field (or default)
|
||||
template_map = {
|
||||
"full": "cms/storefront/landing-full.html",
|
||||
"modern": "cms/storefront/landing-modern.html",
|
||||
"minimal": "cms/storefront/landing-minimal.html",
|
||||
}
|
||||
template_name = "cms/storefront/landing-default.html"
|
||||
if page and page.template:
|
||||
template_name = template_map.get(page.template, template_name)
|
||||
|
||||
return templates.TemplateResponse(template_name, context)
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# DYNAMIC CONTENT PAGES (CMS)
|
||||
# ============================================================================
|
||||
@@ -103,10 +168,13 @@ async def generic_content_page(
|
||||
|
||||
# Resolve placeholders in store default pages ({{store_name}}, etc.)
|
||||
page_content = page.content
|
||||
page_title = page.title
|
||||
if page.is_store_default and store:
|
||||
page_content = content_page_service.resolve_placeholders(page.content, store)
|
||||
page_title = content_page_service.resolve_placeholders(page.title, store)
|
||||
|
||||
context = get_storefront_context(request, db=db, page=page)
|
||||
context["page_title"] = page_title
|
||||
context["page_content"] = page_content
|
||||
|
||||
# Select template based on page.template field
|
||||
|
||||
Reference in New Issue
Block a user