Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const { join } = require("path");
const { format } = require("prettier");
const { enRoot, getFilePaths } = require("./generateTypesForFilesInDocs");
const { read: readMarkdownFile } = require("gray-matter");
const { sidebarLocales } = require("./sidebarLocales");

// This file is the definitive sidebar navigation source. It takes either:
//
Expand All @@ -23,8 +24,25 @@ const { read: readMarkdownFile } = require("gray-matter");
/*
Run this after any changes to propagate:
pnpm run --filter=documentation create-handbook-nav

Sidebar localization data is in: ./sidebarLocales.js
*/

/**
* Get localized text for a given key, with fallback to original.
* @param {string} lang
* @param {string} key - The English text to look up
* @param {"title" | "summary"} field
* @returns {string}
*/
function getLocalizedText(lang, key, field) {
const langMap = sidebarLocales[lang];
if (langMap && langMap[key] && langMap[key][field]) {
return langMap[key][field];
}
return field === "summary" ? key : key; // fallback to original
}

/** @type {HandbookNavItem[]} */
// prettier-ignore
const handbookPages = [
Expand Down Expand Up @@ -244,10 +262,16 @@ for (const lang of langs) {
codeForTheHandbook.push(`navigations.${lang} = [`);

handbookPages.forEach((section, sectionIndex) => {
// Section metadata:
// Section metadata (use localized title/summary for display, but keep id based on English title)
const localizedTitle = getLocalizedText(lang, section.title, "title");
// Look up summary using the section title as key (not the summary text itself)
const langMap = sidebarLocales[lang];
const localizedSummary = (langMap && langMap[section.title] && langMap[section.title].summary)
? langMap[section.title].summary
: section.summary;
codeForTheHandbook.push(`{
title: "${section.title}",
oneline: "${section.summary}",
title: "${localizedTitle}",
oneline: "${localizedSummary}",
id: "${section.title.toLowerCase().replace(/\s/g, "-")}",
chronological: ${section.chronological || false},
`);
Expand All @@ -263,16 +287,25 @@ for (const lang of langs) {

// Is it a special link?
if ("href" in subItem) {
// Use localized title/oneliner for display, keep id based on English title
const localizedLinkTitle = getLocalizedText(lang, subItem.title, "title");
// Look up oneliner using the link title as key
const linkLangMap = sidebarLocales[lang];
const localizedLinkOneliner = (linkLangMap && linkLangMap[subItem.title] && linkLangMap[subItem.title].summary)
? linkLangMap[subItem.title].summary
: subItem.oneliner;
codeForTheHandbook.push(`
title: "${subItem.title}",
title: "${localizedLinkTitle}",
id: "${toID(sectionIndex, subItem.title)}",
permalink: "${subItem.href}",
oneline: "${subItem.oneliner}"
oneline: "${localizedLinkOneliner}"
},`);
} else if ("items" in subItem) {
//Is is a sub-sub-section?
// Use localized title for display, keep id based on English title
const localizedSubTitle = getLocalizedText(lang, subItem.title, "title");
codeForTheHandbook.push(`
title: "${subItem.title}",
title: "${localizedSubTitle}",
id: "${toID(sectionIndex, subItem.title)}",
oneline: "${subItem.oneliner}",
chronological: ${subItem.chronological || false},
Expand All @@ -284,12 +317,16 @@ for (const lang of langs) {
const subNavInfo =
langInfo[lang].get(subItem.file) ||
langInfo["en"].get(subItem.file);
// Get English info for stable id generation
const enNavInfo = langInfo["en"].get(subItem.file);

if (!subNavInfo) throwForUnfoundFile(subItem, lang, langInfo["en"]);

// Use localized title from frontmatter, but keep id based on English title
const enTitle = enNavInfo ? enNavInfo.data.title : subNavInfo.data.title;
codeForTheHandbook.push(`
title: "${subNavInfo.data.short || subNavInfo.data.title}",
id: "${toID(sectionIndex, subNavInfo.data.title)}",
id: "${toID(sectionIndex, enTitle)}",
permalink: "${subNavInfo.data.permalink}",
oneline: "${subNavInfo.data.oneline}",
`);
Expand Down
95 changes: 95 additions & 0 deletions packages/documentation/scripts/sidebarLocales.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// @ts-check
/**
* Sidebar localization data for documentation navigation.
*
* To add a new language:
* 1. Add a new key (e.g., "ja", "ko") to sidebarLocales
* 2. Translate the titles and summaries
* 3. Run: pnpm run --filter=documentation create-handbook-nav
*
* Note: The `id` generation always uses the English title to keep anchors/URLs stable.
* Only display text (title/summary) should be translated here.
*/

/** @type {Record<string, Record<string, { title?: string, summary?: string }>>} */
const sidebarLocales = {
zh: {
// ============================================
// Section titles and summaries (顶级章节)
// ============================================
"Get Started": {
title: "快速开始",
summary: "根据你的背景或偏好快速入门。"
},
"Handbook": {
title: "手册",
summary: "日常 TypeScript 工作的绝佳入门读物。"
},
"Reference": {
title: "参考",
summary: "深入的参考资料。"
},
"Modules Reference": {
title: "模块参考",
summary: "TypeScript 如何处理 JavaScript 模块。"
},
"Tutorials": {
title: "教程",
summary: "在各种环境中使用 TypeScript。"
},
"What's New": {
title: "新增功能",
summary: "了解 TypeScript 的发展历程和各版本的新增功能。"
},
"Declaration Files": {
title: "声明文件",
summary: "学习如何编写声明文件来描述现有的 JavaScript。对 DefinitelyTyped 贡献很重要。"
},
"JavaScript": {
title: "JavaScript",
summary: "如何使用 TypeScript 驱动的 JavaScript 工具。"
},
"Project Configuration": {
title: "项目配置",
summary: "编译器配置参考。"
},

// ============================================
// Sub-section titles (子章节,非文件引用)
// ============================================
"Type Manipulation": { title: "类型操作" },
"Guides": { title: "指南" },
"Appendices": { title: "附录" },
".d.ts Templates": { title: ".d.ts 模板" },

// ============================================
// Special link items (特殊链接)
// ============================================
"Cheat Sheets": {
title: "速查表",
summary: "常见代码的语法概览"
},
"TSConfig Reference": {
title: "TSConfig 参考",
summary: "涵盖所有 TSConfig 选项的页面"
},

// ============================================
// Modules Reference sub-items (模块参考子项)
// ============================================
"Introduction": { title: "简介" },
"Theory": { title: "理论" },
"Choosing Compiler Options": { title: "选择编译器选项" },
// Note: "Reference" is already defined above (used for both section and sub-item)
},

// ============================================
// Add more languages here, e.g.:
// ============================================
// ja: {
// "Get Started": { title: "はじめに", summary: "..." },
// ...
// },
};

module.exports = { sidebarLocales };