Skip to content

Commit 3c5b9ce

Browse files
authored
Fix docs breadcrumb overview routes (#6441)
1 parent 1ef5039 commit 3c5b9ce

2 files changed

Lines changed: 67 additions & 9 deletions

File tree

docs/app/reflex_docs/templates/docpage/docpage.py

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
"""Template for documentation pages."""
22

33
import functools
4+
from collections.abc import Callable, Collection
45
from datetime import datetime
5-
from typing import Callable
66

77
import reflex as rx
88
import reflex_components_internal as ui
@@ -22,6 +22,35 @@
2222
from reflex_site_shared.utils.docpage import right_sidebar_item_highlight
2323
from reflex_site_shared.views.footer import dark_mode_toggle
2424

25+
_REGISTERED_DOC_ROUTES: set[str] = set()
26+
27+
28+
def _normalize_doc_route(path: str) -> str:
29+
"""Normalize a docs route to use leading and trailing slashes."""
30+
route = f"/{path.strip('/')}"
31+
return "/" if route == "/" else f"{route}/"
32+
33+
34+
def _register_doc_route(path: str) -> None:
35+
"""Track a route registered through the docpage template."""
36+
_REGISTERED_DOC_ROUTES.add(_normalize_doc_route(path))
37+
38+
39+
def _resolve_breadcrumb_href(
40+
href: str, registered_routes: Collection[str] | None = None
41+
) -> str:
42+
"""Resolve a generated breadcrumb href to a registered docs route."""
43+
routes = _REGISTERED_DOC_ROUTES if registered_routes is None else registered_routes
44+
route = _normalize_doc_route(href)
45+
if route in routes:
46+
return route
47+
48+
overview_route = _normalize_doc_route(f"{route}overview")
49+
if overview_route in routes:
50+
return overview_route
51+
52+
return href
53+
2554

2655
class FeedbackState(rx.State):
2756
"""Minimal stub for feedback buttons (full implementation removed)."""
@@ -640,20 +669,16 @@ def breadcrumb(path: str, nav_sidebar: rx.Component, doc_content: str | None = N
640669
docs_sidebar_drawer,
641670
)
642671

643-
# Split the path into segments, removing 'docs' and capitalizing each segment
644-
segments = [
645-
segment.capitalize()
646-
for segment in path.split("/")
647-
if segment and segment != "docs"
648-
]
672+
# Split the path into segments, removing 'docs'.
673+
segments = [segment for segment in path.split("/") if segment and segment != "docs"]
649674

650675
# Initialize an empty list to store the breadcrumbs and their separators
651676
breadcrumbs = []
652677

653678
# Iteratively build the href for each segment (paths are app-relative, no /docs prefix)
654679
current_path = ""
655680
for i, segment in enumerate(segments):
656-
current_path += f"/{segment.lower()}"
681+
current_path += f"/{segment}"
657682

658683
# Add the breadcrumb item to the list
659684
breadcrumbs.append(
@@ -662,7 +687,7 @@ def breadcrumb(path: str, nav_sidebar: rx.Component, doc_content: str | None = N
662687
class_name="min-h-8 flex items-center text-sm font-[525] text-m-slate-12 dark:text-m-slate-3 last:text-m-slate-7 dark:last:text-m-slate-6 hover:text-primary-10 dark:hover:text-primary-9"
663688
+ (" truncate" if i == len(segments) - 1 else ""),
664689
underline="none",
665-
href=current_path,
690+
href=_resolve_breadcrumb_href(current_path),
666691
)
667692
)
668693

@@ -746,6 +771,7 @@ def docpage(contents: Callable[[], Route]) -> Route:
746771
The final route with the template applied.
747772
"""
748773
path = get_path(contents, "reflex-docs/pages") if set_path is None else set_path
774+
_register_doc_route(path)
749775

750776
title = contents.__name__.replace("_", " ").title() if t is None else t
751777

docs/app/tests/test_breadcrumbs.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""Tests for docs breadcrumbs."""
2+
3+
import importlib
4+
import sys
5+
from pathlib import Path
6+
7+
import reflex as rx
8+
9+
sys.path.append(str(Path(__file__).resolve().parent.parent))
10+
11+
12+
def test_enterprise_parent_breadcrumb_uses_overview_route(monkeypatch):
13+
"""Parent breadcrumbs should link to a real overview route when needed."""
14+
docpage_module = importlib.import_module("reflex_docs.templates.docpage.docpage")
15+
monkeypatch.setattr(
16+
docpage_module,
17+
"_REGISTERED_DOC_ROUTES",
18+
{
19+
"/enterprise/overview/",
20+
"/enterprise/ag-grid/",
21+
"/enterprise/ag-grid/pivot-mode/",
22+
},
23+
raising=False,
24+
)
25+
26+
rendered = str(
27+
docpage_module.breadcrumb("/enterprise/ag-grid/pivot-mode/", rx.box())
28+
)
29+
30+
assert 'to:"/enterprise/overview/"' in rendered
31+
assert 'to:"/enterprise/ag-grid/"' in rendered
32+
assert 'to:"/enterprise/ag-grid/pivot-mode/"' in rendered

0 commit comments

Comments
 (0)