feat: rank console pages above setup lists

A setup's list for one console is a reference page kept out of the
search index, naming its setup as parent. System pages carry file names
and the platforms' own ids as attribute search fields, never as text.
Arcade gets its own sidebar group.
This commit is contained in:
Abdessamad Derraz committed 2026-10-23 10:36:04 +02:00
1 parent 3d0b013588
commit 5b1120aeb5
2 files changed
+73 -8

No files matched your search

+25 -3
View File
@@ -2205,6 +2205,7 @@ def decorate_markdown_pages(docs: Path) -> dict[str, str]:
description=description, structured=structured, terms=terms,
search=authored.get("search") != "exclude",
logo=str(authored.get("logo") or ""),
parent=authored.get("parent"),
)
write_decorated(docs / target, text)
# One file per page: a page that gained or lost its components
@@ -7509,12 +7510,19 @@ def _emulator_nav(profiles: dict) -> list:
def _system_nav(manufacturers: dict) -> list:
"""Manufacturer pages, the machines apart from the game and engine trees."""
machines, games = [], []
"""Manufacturer pages, the machines apart from the arcade boards and the
game and engine trees: an arcade page's crumb read "Consoles and
computers"."""
machines, arcade, games = [], [], []
for mfr in sorted(manufacturers, key=str.casefold):
entry = {mfr: f"systems/{_slug(mfr)}.md"}
(games if mfr in GAME_DATA_TOPS else machines).append(entry)
if mfr in GAME_DATA_TOPS:
games.append(entry)
else:
(arcade if mfr == "Arcade" else machines).append(entry)
nav: list = ["systems/index.md", {"Consoles and computers": machines}]
if arcade:
nav.append({"Arcade": arcade})
if games:
nav.append({"Game engines and PC games": games})
return nav
@@ -7904,6 +7912,20 @@ def _generate(args: argparse.Namespace) -> None:
if stem in coverages:
raise RuntimeError(f"a system page takes the platform {stem}'s address")
PART_PAGES.add(f"platforms/{stem}.md")
# One console of one setup's list, a reference: "playstation
# bios" found five setups' lists before the console's page.
# Weighed down, they still won on their title, which the page
# weight does not reach, and their file list is already kept out
# of the index: the title alone, found again on the setup's page
# and the console's, is all the search held of them.
SEARCH_DEMOTED.add(f"platforms/{stem}.md")
front = _front_matter(page)
if front:
page = page[page.find("\n---\n", 4) + 5:].lstrip("\n")
front.update(level="reference", search="exclude",
parent={"label": cov["platform"], "link": f"{name}.md"})
page = "---\n" + yaml.safe_dump(front, sort_keys=False, allow_unicode=True) \
+ "---\n\n" + page
write_if_changed(str(docs / "platforms" / f"{stem}.md"), page)
PAGE_DATA[f"platforms/{name}.md"] = platform_structured_data(name, cov)
+48 -5
View File
@@ -368,6 +368,17 @@ def split_title(markdown: str) -> tuple[str, str, str]:
_CARD_NAME = re.compile(r'<h3[^>]*class="rb-file-title"(?![^>]*data-pagefind-ignore)[^>]*><code>([^<]+)</code>')
def search_field(key: str, words: list[str]) -> str:
"""A search field of the page, held in an attribute of an empty
element: the text of an element is indexed and shown as the result's
excerpt (a run of 250 file names). Pagefind splits several fields at a
comma, so a value carries none."""
value = " ".join(word.replace(",", " ") for word in words).strip()
if not value:
return ""
return f'\n<span data-pagefind-meta="{html.escape(f"{key}:{value}", quote=True)}" hidden></span>\n'
def file_names_meta(body: str) -> str:
"""The names of the files a system page holds cards for, as a search
field of the page. A page of 250 cards is long, and the search weighs a
@@ -375,9 +386,35 @@ def file_names_meta(body: str) -> str:
after every short page citing the name. The field is weighted in the
site's ranking (astro.config.mjs, metaWeights.files)."""
names = sorted({unescape(name) for name in _CARD_NAME.findall(body)})
if not names:
return ""
return f'\n<span data-pagefind-meta="files" hidden>{html.escape(" ".join(names))}</span>\n'
return search_field("files", names)
# systems/ page -> the platforms' own ids for the consoles it holds, built
# on the first system page, once the generator has installed the sections.
_page_aliases: dict[str, list[str]] = {}
_page_aliases_built = [False]
def page_aliases(rel: str) -> list[str]:
"""The names the platforms file the consoles of a system page under
(psx, dreamcast, gba), from siterender.system_search_aliases(): "psx
bios" finds the PlayStation page though the page never says psx."""
if not _page_aliases_built[0]:
import siterender
by_page: dict[str, set[str]] = {}
for sys_id in list(siterender._system_page_map):
section = siterender.system_section(sys_id)
names = siterender.system_search_aliases(sys_id)
if not section or not names:
continue
target = siterender.console_href(*section).partition("#")[0]
by_page.setdefault(urllib.parse.unquote(target), set()).update(names)
_page_aliases.clear()
_page_aliases.update({page: sorted(names, key=str.casefold)
for page, names in by_page.items()})
_page_aliases_built[0] = bool(siterender._system_page_map)
return list(_page_aliases.get(rel, []))
_NEXT_STEPS = re.compile(r"^## Next steps\b[^\n]*\n+(?P<list>(?:[ \t]*[-*] .*\n?)+)", re.M)
@@ -407,9 +444,12 @@ def finalize_page(
terms: dict[str, str],
search: bool = True,
logo: str = "",
parent: dict | None = None,
) -> tuple[str, str]:
"""The Starlight file for a page body: its path under the content
collection and its text."""
collection and its text. *parent* ({label, link}, the link written
relative to the page) is the page a part page belongs to: the route
middleware makes it the last crumb and marks it in the sidebar."""
title, title_id, body = split_title(markdown)
body = body.lstrip("\n")
body = rewrite_links(body, rel)
@@ -427,7 +467,7 @@ def finalize_page(
body = re.sub(r'<span class="(rb-badge(?![^"]*rb-badge-archive)[^"]*)"',
r'<span data-pagefind-ignore class="\1"', body)
if rel.startswith("systems/"):
body += file_names_meta(body)
body += file_names_meta(body) + search_field("aliases", page_aliases(rel))
components = used_components(body)
stem = rel.rsplit(".", 1)[0]
if components:
@@ -449,6 +489,9 @@ def finalize_page(
front["level"] = level
if logo:
front["logo"] = logo
if parent:
front["parent"] = {"label": str(parent["label"]),
"link": resolve(rel, str(parent["link"]))}
if weight:
front["searchWeight"] = weight
if rel == NOT_FOUND: