From 288b3caf7f09d5ae2115a5c04d18f71266640a1b Mon Sep 17 00:00:00 2001 From: giles Date: Tue, 24 Feb 2026 11:35:02 +0000 Subject: [PATCH] Add nav-tree fragment: blog renders nav for all apps Blog now provides a nav-tree fragment at /internal/fragments/nav-tree that accepts app_name and path params for correct aria-selected highlighting. Blog itself consumes this fragment alongside cart-mini and auth-menu in a single concurrent fetch_fragments() call. Co-Authored-By: Claude Opus 4.6 --- app.py | 12 +++++------ bp/fragments/routes.py | 18 +++++++++++++++- shared | 2 +- templates/_types/root/header/_header.html | 6 +++++- templates/fragments/nav_tree.html | 26 +++++++++++++++++++++++ 5 files changed, 55 insertions(+), 9 deletions(-) create mode 100644 templates/fragments/nav_tree.html diff --git a/app.py b/app.py index 4db09d0..7824d71 100644 --- a/app.py +++ b/app.py @@ -23,20 +23,16 @@ async def blog_context() -> dict: """ Blog app context processor. - - menu_items: via shared.services.navigation - cart_count/cart_total: via cart service (shared DB) - - cart_mini_html / auth_menu_html: pre-fetched fragments + - cart_mini_html / auth_menu_html / nav_tree_html: pre-fetched fragments """ from shared.infrastructure.context import base_context - 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_fragments ctx = await base_context() - ctx["menu_items"] = await get_navigation_tree(g.s) - # Cart data via service (replaces cross-app HTTP API) ident = current_cart_identity() summary = await services.cart.cart_summary( @@ -55,12 +51,16 @@ async def blog_context() -> dict: auth_params = {"email": user.email} if user else {} - cart_mini_html, auth_menu_html = await fetch_fragments([ + nav_params = {"app_name": "blog", "path": request.path} + + cart_mini_html, auth_menu_html, nav_tree_html = await fetch_fragments([ ("cart", "cart-mini", cart_params or None), ("account", "auth-menu", auth_params or None), + ("blog", "nav-tree", nav_params), ]) 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/bp/fragments/routes.py b/bp/fragments/routes.py index da385b9..07d6e67 100644 --- a/bp/fragments/routes.py +++ b/bp/fragments/routes.py @@ -6,9 +6,10 @@ by other coop apps via the fragment client. from __future__ import annotations -from quart import Blueprint, Response, request +from quart import Blueprint, Response, g, render_template, request from shared.infrastructure.fragments import FRAGMENT_HEADER +from shared.services.navigation import get_navigation_tree def register(): @@ -30,6 +31,21 @@ def register(): html = await handler() return Response(html, status=200, content_type="text/html") + # --- nav-tree fragment --- + async def _nav_tree_handler(): + app_name = request.args.get("app_name", "") + path = request.args.get("path", "/") + first_seg = path.strip("/").split("/")[0] + menu_items = await get_navigation_tree(g.s) + return await render_template( + "fragments/nav_tree.html", + menu_items=menu_items, + frag_app_name=app_name, + frag_first_seg=first_seg, + ) + + _handlers["nav-tree"] = _nav_tree_handler + # Store handlers dict on blueprint so app code can register handlers bp._fragment_handlers = _handlers diff --git a/shared b/shared index 0d40dfa..7e650a0 160000 --- a/shared +++ b/shared @@ -1 +1 @@ -Subproject commit 0d40dfaeca7dbdc8adeaf7b071bfd9faccb74511 +Subproject commit 7e650a0ee3a61d56525cc9e298ed0c4194e780a4 diff --git a/templates/_types/root/header/_header.html b/templates/_types/root/header/_header.html index 33f2c0f..6724edb 100644 --- a/templates/_types/root/header/_header.html +++ b/templates/_types/root/header/_header.html @@ -24,7 +24,11 @@ {# Desktop nav #}