Skip to content

路由层缺少「本地化条目」这层深模块:同一段装配在五个详情页 + 三处列表映射里各写一遍 #47

Description

@SongshGeo

每个详情路由都要自己把「这个条目在这个语言下长什么样」重新拼一遍。拼法一样,
拼的人是七个不同的文件。

详情页:同一段前言抄了五遍

people/[slug].astroprojects/[slug].astroresearch/[slug].astro
resources/[slug].astropublications/[slug].astrogetStaticPaths() 开头
都是同一段:

const entries = await getCollection('X', ({ data }) => data.publish !== false);
const { translations, forLocale } = await relationSources();

return LOCALES.flatMap((lang) => {
  const overlays = translationIndex(translations, COLLECTION_VAULT_PATHS.X, lang);
  const relations = forLocale(lang);
  ...

frontmatter 里也是同一段:

const lang = Astro.params.lang as Lang;
const { Content } = await render(overlay ?? entry);
const isFallback = lang !== 'zh' && !overlay;
const data = localizedData(entry.data, overlay?.data, lang);

为了写出这十行,每个页面要 import 六个名字:entrySlugtranslationIndex
localizedDataisMachineTranslatedCOLLECTION_VAULT_PATHSrelationSources
(再加 coverFor / personAssets)。六个浅接口拼出一个答案,而这个答案对五个
路由是同一个。

#42 §3 记的 isFallback 抄了七遍,是这个问题的一个切面。这里说的是整段装配。)

列表页:view model 映射也各写各的

更糟的是列表页对同一个概念用了不同的helper:

  • people/index.astrotranslationIndex + localizedData,映射出 11 个字段的 Person
  • projects/index.astrolocalizedIndex,映射出 4 个字段的 Person
  • index.astro(首页)又映射一次 Project

三处都在算 entrySlug(p)personAssets(data, slug).avatar
normalizeRole(data.role)detailUrl。三处都可能少算一个字段——
src/components/react/types.ts 的注释就记着这么一次:「restating is how
Project.summary came to exist here, be rendered by HomePage, and be supplied
by nothing.」

建议

缺的是一层深模块:给它一个 collection 和一个 lang,还回来一个可以直接渲染的
条目
。接口小,实现里吃掉 overlay 配对、字段合并、fallback 判定、slug、封面、
URL:

// src/content-layer/localizedEntries.ts
interface LocalizedEntry<T> {
  entry: T;            // 用于 render()
  data: MergedData;    // overlay 覆盖后的 frontmatter
  slug: string;
  href: string;
  cover?: string;
  overlay?: Entry;     // TranslationNotice 自己判断 fallback,不再由页面算
}

// 详情页
const entries = await localizedEntries('research', lang);
// 列表页
const cards = await localizedEntries('people', lang);

判断标准:拆完之后,五个 [slug].astrogetStaticPaths 应该只剩「取集合、
配 relations、组 props」,六个 util import 变成一个;三处 view model 映射变成
一处。

依赖顺序:这件事建议排在 src/utils/ 拆分(另一个 issue)之后做,新模块直接
落在 src/content-layer/

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    tech-debt技术债 / 重构

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions