"""Relations app fragment endpoints. Generic container-nav fragment that renders navigation items for all related entities, driven by the relation registry. """ from __future__ import annotations from quart import Blueprint, Response, g, request from shared.infrastructure.fragments import FRAGMENT_HEADER def register(): bp = Blueprint("fragments", __name__, url_prefix="/internal/fragments") _handlers: dict[str, object] = {} @bp.before_request async def _require_fragment_header(): if not request.headers.get(FRAGMENT_HEADER): return Response("", status=403) @bp.get("/") async def get_fragment(fragment_type: str): handler = _handlers.get(fragment_type) if handler is None: return Response("", status=200, content_type="text/sx") src = await handler() return Response(src, status=200, content_type="text/sx") # --- generic container-nav fragment ---------------------------------------- async def _container_nav_handler(): from shared.sx.helpers import sx_call from shared.sx.relations import relations_from from shared.services.relationships import get_children from shared.infrastructure.urls import events_url, market_url _SERVICE_URL = { "calendar": events_url, "market": market_url, } container_type = request.args.get("container_type", "page") container_id = int(request.args.get("container_id", 0)) post_slug = request.args.get("post_slug", "") nav_class = request.args.get("nav_class", "") exclude_raw = request.args.get("exclude", "") exclude = set(exclude_raw.split(",")) if exclude_raw else set() nav_defs = [ d for d in relations_from(container_type) if d.nav != "hidden" and d.name not in exclude ] if not nav_defs: return "" parts = [] for defn in nav_defs: children = await get_children( g.s, parent_type=container_type, parent_id=container_id, child_type=defn.to_type, relation_type=defn.name, ) for child in children: slug = (child.metadata_ or {}).get("slug", "") if not slug: continue if post_slug: path = f"/{post_slug}/{slug}/" else: path = f"/{slug}/" url_fn = _SERVICE_URL.get(defn.to_type) href = url_fn(path) if url_fn else path parts.append(sx_call("relation-nav", href=href, name=child.label or "", icon=defn.nav_icon or "", nav_class=nav_class, relation_type=defn.name)) if not parts: return "" return "(<> " + " ".join(parts) + ")" _handlers["container-nav"] = _container_nav_handler return bp