Unify post admin nav across all services
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m56s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m56s
Move post admin header into shared/sexp/helpers.py so blog, cart, events, and market all render the same admin row with identical nav: calendars | markets | payments | entries | data | edit | settings. All links are external (cross-service). The selected item shows highlighted on the right and as white text next to "admin" on the left. - blog: delegates to shared helper, removes blog-specific nav builder - cart: delegates to shared helper for payments admin - events: adds shared admin row (selected=calendars) to calendar admin - market: adds /<slug>/admin/ route + page_admin blueprint, delegates to shared helper (selected=markets). Fixes 404 on page-level admin. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -16,6 +16,7 @@ from shared.sexp.jinja_bridge import render, load_service_components
|
||||
from shared.sexp.helpers import (
|
||||
call_url, get_asset_url, root_header_html,
|
||||
post_header_html as _shared_post_header_html,
|
||||
post_admin_header_html as _shared_post_admin_header_html,
|
||||
oob_header_html,
|
||||
search_mobile_html, search_desktop_html,
|
||||
full_page, oob_page,
|
||||
@@ -87,81 +88,9 @@ def _post_header_html(ctx: dict, *, oob: bool = False) -> str:
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def _post_admin_header_html(ctx: dict, *, oob: bool = False, selected: str = "") -> str:
|
||||
"""Post admin header row with admin icon and nav links."""
|
||||
from quart import url_for as qurl
|
||||
|
||||
post = ctx.get("post") or {}
|
||||
slug = post.get("slug", "")
|
||||
hx_select = ctx.get("hx_select_search", "#main-panel")
|
||||
select_colours = ctx.get("select_colours", "")
|
||||
styles = ctx.get("styles") or {}
|
||||
nav_btn = styles.get("nav_button", "") if isinstance(styles, dict) else getattr(styles, "nav_button", "")
|
||||
|
||||
admin_href = qurl("blog.post.admin.admin", slug=slug)
|
||||
label_html = render("blog-admin-label")
|
||||
if selected:
|
||||
label_html += f' <span class="text-white">{escape(selected)}</span>'
|
||||
|
||||
nav_html = _post_admin_nav_html(ctx, selected=selected)
|
||||
|
||||
return render("menu-row",
|
||||
id="post-admin-row", level=2,
|
||||
link_href=admin_href, link_label_html=label_html,
|
||||
nav_html=nav_html, child_id="post-admin-header-child", oob=oob,
|
||||
)
|
||||
|
||||
|
||||
def _post_admin_nav_html(ctx: dict, *, selected: str = "") -> str:
|
||||
"""Post admin desktop nav: calendars, markets, payments, entries, data, edit, settings."""
|
||||
from quart import url_for as qurl
|
||||
|
||||
post = ctx.get("post") or {}
|
||||
slug = post.get("slug", "")
|
||||
hx_select = ctx.get("hx_select_search", "#main-panel")
|
||||
select_colours = ctx.get("select_colours", "")
|
||||
styles = ctx.get("styles") or {}
|
||||
nav_btn = styles.get("nav_button", "") if isinstance(styles, dict) else getattr(styles, "nav_button", "")
|
||||
|
||||
# Base and selected class for nav items
|
||||
base_cls = "justify-center cursor-pointer flex flex-row items-center gap-2 rounded bg-stone-200 text-black p-3"
|
||||
selected_cls = "justify-center cursor-pointer flex flex-row items-center gap-2 rounded !bg-stone-500 !text-white p-3"
|
||||
|
||||
parts = []
|
||||
|
||||
# External links to events / market services
|
||||
events_url_fn = ctx.get("events_url")
|
||||
market_url_fn = ctx.get("market_url")
|
||||
if callable(events_url_fn):
|
||||
for url_fn, path, label in [
|
||||
(events_url_fn, f"/{slug}/admin/", "calendars"),
|
||||
(market_url_fn, f"/{slug}/admin/", "markets"),
|
||||
(ctx.get("cart_url"), f"/{slug}/admin/payments/", "payments"),
|
||||
]:
|
||||
if not callable(url_fn):
|
||||
continue
|
||||
href = url_fn(path)
|
||||
cls = selected_cls if label == selected else (nav_btn or base_cls)
|
||||
parts.append(render("blog-admin-nav-item",
|
||||
href=href, nav_btn_class=cls, label=label,
|
||||
select_colours=select_colours,
|
||||
))
|
||||
|
||||
# HTMX links
|
||||
for endpoint, label in [
|
||||
("blog.post.admin.entries", "entries"),
|
||||
("blog.post.admin.data", "data"),
|
||||
("blog.post.admin.edit", "edit"),
|
||||
("blog.post.admin.settings", "settings"),
|
||||
]:
|
||||
href = qurl(endpoint, slug=slug)
|
||||
is_sel = label == selected
|
||||
parts.append(render("nav-link",
|
||||
href=href, label=label, select_colours=select_colours,
|
||||
is_selected=is_sel,
|
||||
aclass=(selected_cls + " " + select_colours) if is_sel else None,
|
||||
))
|
||||
|
||||
return "".join(parts)
|
||||
"""Post admin header row — delegates to shared helper."""
|
||||
slug = (ctx.get("post") or {}).get("slug", "")
|
||||
return _shared_post_admin_header_html(ctx, slug, oob=oob, selected=selected)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user