「一个 collection 的条目 URL 长什么样」这件事,在 14 个文件里各写了一遍,一共 19 处。
证据
src/utils/relations.ts:246 `/${lang}/${collection}/${slug}` ← 唯一一处真正的实现
src/pages/[lang]/index.astro:74 `/${lang}/projects/${entrySlug(project)}`
src/pages/[lang]/projects/index.astro:73 `/${lang}/projects/${entrySlug(project)}`
src/pages/[lang]/people/index.astro:48 `/${lang}/people/${slug}`
src/pages/[lang]/news/index.astro:40 `/${lang}/people/${person.slug}`
src/pages/[lang]/library/index.astro:28 `/${lang}/library/${slug}`
src/pages/[lang]/research/index.astro:45 `/${lang}/research/${entrySlug(theme)}`
src/pages/[lang]/resources/index.astro:69 `/${lang}/resources/${resource.slug}`
src/pages/[lang]/publications/index.astro:27 `/${lang}/publications/${pub.data.bib_key ?? pub.id}`
src/pages/[lang]/library/[...slug].astro:129 `/${lang}/library`
src/components/Header.astro:22 `/${lang}/`
(grep -rn '\${lang}/' src → 19 处。)
更糟的是 React 侧又算了第二遍
服务端算好 detailUrl 塞进 props,客户端组件却不信它,自己再拼一次兜底:
// HomePage.tsx:106
href={project.detailUrl || `/${lang}/projects/${project.id}`}
// PeoplePage.tsx:19
href={person.detailUrl || `/${lang}/people/${person.id}`}
// ProjectsPage.tsx:35, LibraryPage.tsx:26 同样
这些兜底目前算出来的 URL 和主路径一致,所以没在线上出事——但那是巧合:它成立
的前提是 view model 的 id 恰好就是 slug,而各个 collection 并不一致
(publications 按 citation key,library 用的是 slug 字段而不是 id)。这是一份
从来没有被执行、因此也从来没有被验证过的第二实现,路由形状一改它就会静默地
指向 404。
建议
抽一个路由模块,让它成为唯一知道 URL 形状的地方:
// src/routes.ts
export function href(lang: Lang, collection: RelCollection, slug: string): string;
export function indexHref(lang: Lang, collection: RelCollection): string;
export function homeHref(lang: Lang): string;
relations.ts:246 改成调它,19 处手写改成调它,React 组件的 || ... 兜底直接
删掉——props 里的 detailUrl 要么有值,要么这个条目就没有页面(publications
里没有 sidecar 的论文就是这种情况,types.ts 已经写清楚了)。
顺带一提,href 里也是唯一适合放「哪个 collection 有独立页面」这个判断的地方;
现在它散在 relations.ts 的 spec.hasPage(data) 和各个组件的 || 里。
「一个 collection 的条目 URL 长什么样」这件事,在 14 个文件里各写了一遍,一共 19 处。
证据
(
grep -rn '\${lang}/' src→ 19 处。)更糟的是 React 侧又算了第二遍
服务端算好
detailUrl塞进 props,客户端组件却不信它,自己再拼一次兜底:这些兜底目前算出来的 URL 和主路径一致,所以没在线上出事——但那是巧合:它成立
的前提是 view model 的
id恰好就是 slug,而各个 collection 并不一致(publications 按 citation key,library 用的是
slug字段而不是id)。这是一份从来没有被执行、因此也从来没有被验证过的第二实现,路由形状一改它就会静默地
指向 404。
建议
抽一个路由模块,让它成为唯一知道 URL 形状的地方:
relations.ts:246改成调它,19 处手写改成调它,React 组件的|| ...兜底直接删掉——props 里的
detailUrl要么有值,要么这个条目就没有页面(publications里没有 sidecar 的论文就是这种情况,
types.ts已经写清楚了)。顺带一提,
href里也是唯一适合放「哪个 collection 有独立页面」这个判断的地方;现在它散在
relations.ts的spec.hasPage(data)和各个组件的||里。