From 8b52a11b673b625710ce5027db6d5ede9f736ede Mon Sep 17 00:00:00 2001 From: giles Date: Tue, 24 Feb 2026 20:26:20 +0000 Subject: [PATCH] Add cart-mini + auth-menu fragments to all apps, fix like button - Market, events, federation, account now fetch cart-mini, auth-menu, and nav-tree fragments concurrently (matching blog's pattern) - Move like button template to shared/browser/templates/ so blog can find it without needing market's templates in its container Co-Authored-By: Claude Opus 4.6 --- account/app.py | 23 +++++++++++++++---- events/app.py | 23 +++++++++++++++---- federation/app.py | 23 +++++++++++++++---- market/app.py | 23 +++++++++++++++---- .../templates/_types/browse/like/button.html | 20 ++++++++++++++++ 5 files changed, 92 insertions(+), 20 deletions(-) create mode 100644 shared/browser/templates/_types/browse/like/button.html diff --git a/account/app.py b/account/app.py index c23ff3d..5ae8fe3 100644 --- a/account/app.py +++ b/account/app.py @@ -16,14 +16,10 @@ async def account_context() -> dict: from shared.infrastructure.context import base_context from shared.services.navigation import get_navigation_tree from shared.infrastructure.cart_identity import current_cart_identity - from shared.infrastructure.fragments import fetch_fragment + from shared.infrastructure.fragments import fetch_fragments ctx = await base_context() - ctx["nav_tree_html"] = await fetch_fragment( - "blog", "nav-tree", - params={"app_name": "account", "path": request.path}, - ) # Fallback for _nav.html when nav-tree fragment fetch fails ctx["menu_items"] = await get_navigation_tree(g.s) @@ -35,6 +31,23 @@ async def account_context() -> dict: ctx["cart_count"] = summary.count + summary.calendar_count + summary.ticket_count ctx["cart_total"] = float(summary.total + summary.calendar_total + summary.ticket_total) + # Pre-fetch cross-app HTML fragments concurrently + user = getattr(g, "user", None) + cart_params = {} + if ident["user_id"] is not None: + cart_params["user_id"] = ident["user_id"] + if ident["session_id"] is not None: + cart_params["session_id"] = ident["session_id"] + + cart_mini_html, auth_menu_html, nav_tree_html = await fetch_fragments([ + ("cart", "cart-mini", cart_params or None), + ("account", "auth-menu", {"email": user.email} if user else None), + ("blog", "nav-tree", {"app_name": "account", "path": request.path}), + ]) + ctx["cart_mini_html"] = cart_mini_html + ctx["auth_menu_html"] = auth_menu_html + ctx["nav_tree_html"] = nav_tree_html + return ctx diff --git a/events/app.py b/events/app.py index 48bb697..ac5bfe9 100644 --- a/events/app.py +++ b/events/app.py @@ -22,14 +22,10 @@ async def events_context() -> dict: from shared.services.navigation import get_navigation_tree from shared.services.registry import services from shared.infrastructure.cart_identity import current_cart_identity - from shared.infrastructure.fragments import fetch_fragment + from shared.infrastructure.fragments import fetch_fragments ctx = await base_context() - ctx["nav_tree_html"] = await fetch_fragment( - "blog", "nav-tree", - params={"app_name": "events", "path": request.path}, - ) # Fallback for _nav.html when nav-tree fragment fetch fails ctx["menu_items"] = await get_navigation_tree(g.s) @@ -41,6 +37,23 @@ async def events_context() -> dict: ctx["cart_count"] = summary.count + summary.calendar_count + summary.ticket_count ctx["cart_total"] = float(summary.total + summary.calendar_total + summary.ticket_total) + # Pre-fetch cross-app HTML fragments concurrently + user = getattr(g, "user", None) + cart_params = {} + if ident["user_id"] is not None: + cart_params["user_id"] = ident["user_id"] + if ident["session_id"] is not None: + cart_params["session_id"] = ident["session_id"] + + cart_mini_html, auth_menu_html, nav_tree_html = await fetch_fragments([ + ("cart", "cart-mini", cart_params or None), + ("account", "auth-menu", {"email": user.email} if user else None), + ("blog", "nav-tree", {"app_name": "events", "path": request.path}), + ]) + ctx["cart_mini_html"] = cart_mini_html + ctx["auth_menu_html"] = auth_menu_html + ctx["nav_tree_html"] = nav_tree_html + return ctx diff --git a/federation/app.py b/federation/app.py index ac8c6d0..5d68f04 100644 --- a/federation/app.py +++ b/federation/app.py @@ -20,14 +20,10 @@ async def federation_context() -> dict: from shared.infrastructure.context import base_context from shared.services.navigation import get_navigation_tree from shared.infrastructure.cart_identity import current_cart_identity - from shared.infrastructure.fragments import fetch_fragment + from shared.infrastructure.fragments import fetch_fragments ctx = await base_context() - ctx["nav_tree_html"] = await fetch_fragment( - "blog", "nav-tree", - params={"app_name": "federation", "path": request.path}, - ) # Fallback for _nav.html when nav-tree fragment fetch fails ctx["menu_items"] = await get_navigation_tree(g.s) @@ -39,6 +35,23 @@ async def federation_context() -> dict: ctx["cart_count"] = summary.count + summary.calendar_count + summary.ticket_count ctx["cart_total"] = float(summary.total + summary.calendar_total + summary.ticket_total) + # Pre-fetch cross-app HTML fragments concurrently + user = getattr(g, "user", None) + cart_params = {} + if ident["user_id"] is not None: + cart_params["user_id"] = ident["user_id"] + if ident["session_id"] is not None: + cart_params["session_id"] = ident["session_id"] + + cart_mini_html, auth_menu_html, nav_tree_html = await fetch_fragments([ + ("cart", "cart-mini", cart_params or None), + ("account", "auth-menu", {"email": user.email} if user else None), + ("blog", "nav-tree", {"app_name": "federation", "path": request.path}), + ]) + ctx["cart_mini_html"] = cart_mini_html + ctx["auth_menu_html"] = auth_menu_html + ctx["nav_tree_html"] = nav_tree_html + # Actor profile for logged-in users if g.get("user"): actor = await services.federation.get_actor_by_user_id(g.s, g.user.id) diff --git a/market/app.py b/market/app.py index bbfcbcf..c551a54 100644 --- a/market/app.py +++ b/market/app.py @@ -25,16 +25,12 @@ async def market_context() -> dict: from shared.services.navigation import get_navigation_tree from shared.services.registry import services from shared.infrastructure.cart_identity import current_cart_identity - from shared.infrastructure.fragments import fetch_fragment + from shared.infrastructure.fragments import fetch_fragments from shared.models.market import CartItem from sqlalchemy.orm import selectinload ctx = await base_context() - ctx["nav_tree_html"] = await fetch_fragment( - "blog", "nav-tree", - params={"app_name": "market", "path": request.path}, - ) # Fallback for _nav.html when nav-tree fragment fetch fails ctx["menu_items"] = await get_navigation_tree(g.s) @@ -47,6 +43,23 @@ async def market_context() -> dict: ctx["cart_count"] = summary.count + summary.calendar_count ctx["cart_total"] = float(summary.total + summary.calendar_total) + # Pre-fetch cross-app HTML fragments concurrently + user = getattr(g, "user", None) + cart_params = {} + if ident["user_id"] is not None: + cart_params["user_id"] = ident["user_id"] + if ident["session_id"] is not None: + cart_params["session_id"] = ident["session_id"] + + cart_mini_html, auth_menu_html, nav_tree_html = await fetch_fragments([ + ("cart", "cart-mini", cart_params or None), + ("account", "auth-menu", {"email": user.email} if user else None), + ("blog", "nav-tree", {"app_name": "market", "path": request.path}), + ]) + ctx["cart_mini_html"] = cart_mini_html + ctx["auth_menu_html"] = auth_menu_html + ctx["nav_tree_html"] = nav_tree_html + # ORM cart items for product templates (need .product relationship) filters = [CartItem.deleted_at.is_(None)] if ident["user_id"] is not None: diff --git a/shared/browser/templates/_types/browse/like/button.html b/shared/browser/templates/_types/browse/like/button.html new file mode 100644 index 0000000..426bdc1 --- /dev/null +++ b/shared/browser/templates/_types/browse/like/button.html @@ -0,0 +1,20 @@ +