From 06a44e55e7a46c3de30a6f26b777b704e32754bb Mon Sep 17 00:00:00 2001 From: Samir Boulahtit Date: Sat, 16 May 2026 19:46:17 +0200 Subject: [PATCH] feat(storefront): translatable Store description + nav home key + dynamic html lang Three small storefront i18n improvements found during the FR pre-launch walkthrough on FASHIONHUB: - Store description (e.g. "Trendy clothing and accessories") was a single English string rendering in the footer regardless of locale. Added a description_translations JSON column on Store with the same shape used elsewhere (CMS, Platform, Subscription), exposed via get_translated_description(lang), and updated the footer + meta tag to use it. Seeded FR/DE/LB/EN for FASHIONHUB and FASHIONOUTLET so Fashion Group renders correctly out of the box. Other stores still show the single description field as fallback. - "Home" was a hardcoded English literal in both desktop and mobile nav, even though the FR translation already existed at nav.home in static/locales/fr.json. Now uses _('nav.home'). - was hardcoded, which made show in mm/dd/yyyy on the FR storefront. Now driven by current_language so the browser's locale-aware date picker matches the page locale. Migration tenancy_005 adds the description_translations column; nullable, no backfill needed. Co-Authored-By: Claude Opus 4.7 (1M context) --- ..._005_add_store_description_translations.py | 31 +++++++++++++++++++ app/modules/tenancy/models/store.py | 15 +++++++++ app/templates/storefront/base.html | 10 +++--- scripts/seed/seed_demo.py | 13 ++++++++ 4 files changed, 64 insertions(+), 5 deletions(-) create mode 100644 app/modules/tenancy/migrations/versions/tenancy_005_add_store_description_translations.py diff --git a/app/modules/tenancy/migrations/versions/tenancy_005_add_store_description_translations.py b/app/modules/tenancy/migrations/versions/tenancy_005_add_store_description_translations.py new file mode 100644 index 00000000..eec78b3d --- /dev/null +++ b/app/modules/tenancy/migrations/versions/tenancy_005_add_store_description_translations.py @@ -0,0 +1,31 @@ +"""add description_translations to stores + +Revision ID: tenancy_005 +Revises: tenancy_004 +Create Date: 2026-05-16 +""" + +import sqlalchemy as sa + +from alembic import op + +revision = "tenancy_005" +down_revision = "tenancy_004" +branch_labels = None +depends_on = None + + +def upgrade() -> None: + op.add_column( + "stores", + sa.Column( + "description_translations", + sa.JSON(), + nullable=True, + comment="Language-keyed description dict for multi-language support", + ), + ) + + +def downgrade() -> None: + op.drop_column("stores", "description_translations") diff --git a/app/modules/tenancy/models/store.py b/app/modules/tenancy/models/store.py index 3f6d06e9..b6937496 100644 --- a/app/modules/tenancy/models/store.py +++ b/app/modules/tenancy/models/store.py @@ -56,6 +56,11 @@ class Store(Base, TimestampMixin, SoftDeleteMixin): String, nullable=False ) # Non-nullable name column for the store (brand name) description = Column(Text) # Optional text description column for the store + description_translations = Column( + JSON, + nullable=True, + comment="Language-keyed description dict for multi-language support", + ) # Letzshop URLs - multi-language support (brand-specific marketplace feeds) letzshop_csv_url_fr = Column(String) # URL for French CSV in Letzshop @@ -320,6 +325,16 @@ class Store(Base, TimestampMixin, SoftDeleteMixin): "logo" ) # Return None or the logo URL if found + def get_translated_description(self, lang: str, default_lang: str = "fr") -> str | None: + """Get description in the given language, falling back to default_lang then self.description.""" + if self.description_translations: + return ( + self.description_translations.get(lang) + or self.description_translations.get(default_lang) + or self.description + ) + return self.description + # ======================================================================== # Domain Helper Methods # ======================================================================== diff --git a/app/templates/storefront/base.html b/app/templates/storefront/base.html index 94f1e46d..26786518 100644 --- a/app/templates/storefront/base.html +++ b/app/templates/storefront/base.html @@ -1,7 +1,7 @@ {# app/templates/storefront/base.html #} {# Base template for store shop frontend with theme support #} - + @@ -13,7 +13,7 @@ {# SEO Meta Tags #} - + {# Favicon - store-specific or default #} {% if theme.branding.favicon %} @@ -89,7 +89,7 @@ {# Navigation — Home is always shown, module items are dynamic #}