fix: order category page JSON-LD ItemList to match rendered rows

Category pages' JSON-LD ItemList listed entries in download order while the table renders them in README (editorial) order, so structured-data positions didn't match the visible rows.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Vinta Chen
2026-09-27 14:47:00 +08:00
co-authored by Claude
parent 5c4607dd0f
commit f0ebe92155
2 changed files with 35 additions and 1 deletions
+2 -1
View File
@@ -755,8 +755,9 @@ def build(repo_root: Path) -> None:
if parent_category:
breadcrumbs.append((parent_category["name"], category_public_url(parent_category)))
breadcrumbs.append((category["name"], category_url))
page_entries = [entry for group in entry_groups for entry in group["entries"]] if entry_groups else entries
category_json_ld = json.dumps(
build_category_json_ld(category_title.removesuffix(" - Awesome Python"), category_url, category_description, entries, breadcrumbs),
build_category_json_ld(category_title.removesuffix(" - Awesome Python"), category_url, category_description, page_entries, breadcrumbs),
ensure_ascii=False,
).replace("</", "<\\/")
(page_dir / "index.html").write_text(
+33
View File
@@ -679,6 +679,39 @@ class TestBuild:
{"@type": "ListItem", "position": 2, "name": "Widgets", "item": "https://awesome-python.com/categories/widgets/"},
]
def test_category_json_ld_follows_page_order(self, tmp_path):
readme = textwrap.dedent("""\
# Awesome Python
Intro.
## Projects
**Tools**
## Widgets
_Widget libraries._
- [zeta](https://example.com/zeta) - Listed first.
- [alpha](https://example.com/alpha) - Listed second.
# Contributing
Help!
""")
(tmp_path / "README.md").write_text(readme, encoding="utf-8")
self._copy_real_templates(tmp_path)
build(tmp_path)
category_html = (tmp_path / "website" / "output" / "categories" / "widgets" / "index.html").read_text(encoding="utf-8")
marker = '<script type="application/ld+json">'
start = category_html.index(marker) + len(marker)
data = json.loads(category_html[start : category_html.index("</script>", start)])
collection = next(node for node in data["@graph"] if node["@type"] == "CollectionPage")
items = collection["mainEntity"]["itemListElement"]
assert [(item["position"], item["name"]) for item in items] == [(1, "zeta"), (2, "alpha")]
def test_group_page_falls_back_to_default_description_in_json_ld(self, tmp_path):
readme = textwrap.dedent("""\
# T