feat(cms): CMS-driven homepages, products section, placeholder resolution
Some checks failed
Some checks failed
- Add ProductCard/ProductsSection schema and _products.html section macro
- Rewrite seed script with 3-platform homepage sections (wizard, OMS, loyalty),
platform marketing pages, and store defaults with {{store_name}} placeholders
- Add resolve_placeholders() to ContentPageService for store default pages
- Fix SQLAlchemy filter bugs: replace Python `is None` with `.is_(None)` across
all ContentPageService query methods (was silently breaking all platform page lookups)
- Remove hardcoded orion fallback and delete homepage-orion.html
- Add placeholder hint box with click-to-copy in admin content page editor
- Export ProductCard/ProductsSection from cms schemas __init__
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -77,6 +77,25 @@ class FeatureCard(BaseModel):
|
||||
description: TranslatableText = Field(default_factory=TranslatableText)
|
||||
|
||||
|
||||
class ProductCard(BaseModel):
|
||||
"""Single product/offering card in products section."""
|
||||
|
||||
icon: str = ""
|
||||
title: TranslatableText = Field(default_factory=TranslatableText)
|
||||
description: TranslatableText = Field(default_factory=TranslatableText)
|
||||
url: str = ""
|
||||
badge: TranslatableText | None = None
|
||||
|
||||
|
||||
class ProductsSection(BaseModel):
|
||||
"""Product/offering showcase section (e.g. wizard.lu multi-product landing)."""
|
||||
|
||||
enabled: bool = True
|
||||
title: TranslatableText = Field(default_factory=TranslatableText)
|
||||
subtitle: TranslatableText | None = None
|
||||
products: list[ProductCard] = Field(default_factory=list)
|
||||
|
||||
|
||||
class FeaturesSection(BaseModel):
|
||||
"""Features section configuration."""
|
||||
|
||||
@@ -114,6 +133,7 @@ class HomepageSections(BaseModel):
|
||||
"""Complete homepage sections structure."""
|
||||
|
||||
hero: HeroSection | None = None
|
||||
products: ProductsSection | None = None
|
||||
features: FeaturesSection | None = None
|
||||
pricing: PricingSection | None = None
|
||||
cta: CTASection | None = None
|
||||
@@ -139,6 +159,10 @@ class HomepageSections(BaseModel):
|
||||
subtitle=make_translatable(languages),
|
||||
buttons=[],
|
||||
),
|
||||
products=ProductsSection(
|
||||
title=make_translatable(languages),
|
||||
products=[],
|
||||
),
|
||||
features=FeaturesSection(
|
||||
title=make_translatable(languages),
|
||||
features=[],
|
||||
@@ -162,7 +186,7 @@ class HomepageSections(BaseModel):
|
||||
class SectionUpdateRequest(BaseModel):
|
||||
"""Request to update a single section."""
|
||||
|
||||
section_name: str = Field(..., description="hero, features, pricing, or cta")
|
||||
section_name: str = Field(..., description="hero, products, features, pricing, or cta")
|
||||
section_data: dict = Field(..., description="Section configuration")
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user