feat(i18n): Simplified Chinese (zh-CN), search answers per locale, fr/de/es data fixes
CI / Lint e auditorias (push) Successful in 1m10s
CI / Trivy (dependências e segredos) (push) Successful in 12s
CI / Imagem Docker (linux/arm64) (push) Successful in 2m39s
Release / Plano (reaproveitar a imagem?) (push) Successful in 6s
Release / ci (push) Skipped
Release / Publica a imagem (linux/arm64) (push) Successful in 18s
Release / Cria a release no Gitea (push) Successful in 5s

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Lucas RayanandClaude Sonnet 5.5 committed 2026-11-01 23:28:39 -03:00
1 parent ae61416468
commit 5a9fe676fc
61 files changed
+2517 -920

No files matched your search

+47 -6
View File
@@ -33,6 +33,20 @@ import { errosCatalogo as errosDe } from "@/lib/data/de/diagnostico";
import { COMPONENTES_REGISTRY as componentesDe } from "@/lib/data/de/componentes";
import { montarConhecimento as montarConhecimentoDe } from "@/lib/data/de/topicos";
import seriesDataZh from "@/data/zh-CN/series.json";
import frameworksDataZh from "@/data/zh-CN/frameworks.json";
import { categoriasGlossario as glossarioZh } from "@/lib/data/zh-CN/glossario";
import { errosCatalogo as errosZh } from "@/lib/data/zh-CN/diagnostico";
import { COMPONENTES_REGISTRY as componentesZh } from "@/lib/data/zh-CN/componentes";
import { montarConhecimento as montarConhecimentoZh } from "@/lib/data/zh-CN/topicos";
// Nomes, rótulos e sinônimos dos assuntos no idioma da página (o motor só traz os em português).
import { TOPICOS as TOPICOS_EN } from "@/lib/data/en/topicos";
import { TOPICOS as TOPICOS_ES } from "@/lib/data/es/topicos";
import { TOPICOS as TOPICOS_FR } from "@/lib/data/fr/topicos";
import { TOPICOS as TOPICOS_DE } from "@/lib/data/de/topicos";
import { TOPICOS as TOPICOS_ZH } from "@/lib/data/zh-CN/topicos";
import { readFileSync, existsSync } from "node:fs";
import path from "node:path";
@@ -97,6 +111,19 @@ const PAGINAS_FR = [
{ titulo: "À Propos du Projet", descricao: "Histoire, auteur et open source", href: "/fr/a-propos", keywords: "auteur contact open source" },
];
const PAGINAS_ZH = [
{ titulo: "首页", descricao: "ESPDocs 首页", href: "/zh-CN", keywords: "首页 主页 home" },
{ titulo: "全部系列", descricao: "每个 ESP32 系列的引脚、规格与限制", href: "/zh-CN/series", keywords: "芯片 引脚 规格 pinout" },
{ titulo: "系列对比", descricao: "最多并排对比 4 个型号", href: "/zh-CN/compare", keywords: "对比 比较 差异" },
{ titulo: "开发板目录", descricao: "开发板、引脚与购买渠道", href: "/zh-CN/catalog", keywords: "开发板 devkit 购买" },
{ titulo: "智能选型", descricao: "为你的项目找到合适的芯片", href: "/zh-CN/selector", keywords: "选型 推荐 测验" },
{ titulo: "故障诊断", descricao: "排查 Brownout、启动循环、看门狗和崩溃", href: "/zh-CN/diagnostics", keywords: "故障 错误 崩溃 问题 bug" },
{ titulo: "框架与 SDK", descricao: "ESP-IDF、Arduino、Rust、RainMaker 等", href: "/zh-CN/frameworks", keywords: "sdk 开发框架" },
{ titulo: "Component Registry", descricao: "驱动目录与 idf_component.yml 生成器", href: "/zh-CN/components", keywords: "库 驱动 组件 yml" },
{ titulo: "技术术语表", descricao: "关键的硬件与软件概念", href: "/zh-CN/glossary", keywords: "术语 词典 定义 含义" },
{ titulo: "关于本项目", descricao: "历史、作者与开源", href: "/zh-CN/about", keywords: "作者 联系 开源" },
];
const PAGINAS_DE = [
{ titulo: "Startseite", descricao: "ESPDocs Startseite", href: "/de", keywords: "startseite home" },
{ titulo: "Alle Serien", descricao: "Pinbelegungen, Spezifikationen und Einschränkungen für jede ESP32-Serie", href: "/de/serien", keywords: "chips pinbelegung spezifikationen pinout" },
@@ -117,6 +144,7 @@ export function construirIndiceBusca(locale = "pt") {
const isEs = locale === "es";
const isFr = locale === "fr";
const isDe = locale === "de";
const isZh = locale === "zh-CN";
let paginas = PAGINAS_PT;
let seriesData = seriesDataPt;
@@ -158,13 +186,21 @@ export function construirIndiceBusca(locale = "pt") {
errosCatalogo = errosDe;
componentes = componentesDe;
montarConhecimento = montarConhecimentoDe;
} else if (isZh) {
paginas = PAGINAS_ZH;
seriesData = seriesDataZh;
frameworksData = frameworksDataZh;
categoriasGlossario = glossarioZh;
errosCatalogo = errosZh;
componentes = componentesZh;
montarConhecimento = montarConhecimentoZh;
}
const slugSeries = isDe ? "/de/serien" : isFr ? "/fr/series" : isEn ? "/en/series" : isEs ? "/es/series" : "/series";
const slugFrameworks = isDe ? "/de/frameworks" : isFr ? "/fr/frameworks" : isEn ? "/en/frameworks" : isEs ? "/es/frameworks" : "/frameworks";
const slugGlossario = isDe ? "/de/glossar" : isFr ? "/fr/glossaire" : isEn ? "/en/glossary" : isEs ? "/es/glosario" : "/glossario";
const slugDiagnostico = isDe ? "/de/diagnose" : isFr ? "/fr/diagnostic" : isEn ? "/en/diagnostics" : isEs ? "/es/diagnostico" : "/diagnostico";
const slugComponentes = isDe ? "/de/komponenten" : isFr ? "/fr/composants" : isEn ? "/en/components" : isEs ? "/es/componentes" : "/componentes";
const slugSeries = isZh ? "/zh-CN/series" : isDe ? "/de/serien" : isFr ? "/fr/series" : isEn ? "/en/series" : isEs ? "/es/series" : "/series";
const slugFrameworks = isZh ? "/zh-CN/frameworks" : isDe ? "/de/frameworks" : isFr ? "/fr/frameworks" : isEn ? "/en/frameworks" : isEs ? "/es/frameworks" : "/frameworks";
const slugGlossario = isZh ? "/zh-CN/glossary" : isDe ? "/de/glossar" : isFr ? "/fr/glossaire" : isEn ? "/en/glossary" : isEs ? "/es/glosario" : "/glossario";
const slugDiagnostico = isZh ? "/zh-CN/diagnostics" : isDe ? "/de/diagnose" : isFr ? "/fr/diagnostic" : isEn ? "/en/diagnostics" : isEs ? "/es/diagnostico" : "/diagnostico";
const slugComponentes = isZh ? "/zh-CN/components" : isDe ? "/de/komponenten" : isFr ? "/fr/composants" : isEn ? "/en/components" : isEs ? "/es/componentes" : "/componentes";
const itens = [];
@@ -233,7 +269,7 @@ export function construirIndiceBusca(locale = "pt") {
? path.join(process.cwd(), "data", "es", "conexoes")
: isFr
? path.join(process.cwd(), "data", "fr", "conexoes")
: isDe
: isZh ? path.join(process.cwd(), "data", "zh-CN", "conexoes") : isDe
? path.join(process.cwd(), "data", "de", "conexoes")
: path.join(process.cwd(), "public", "conexoes");
const arquivo = path.join(pastaConexoes, `${chave}.json`);
@@ -245,7 +281,12 @@ export function construirIndiceBusca(locale = "pt") {
}
}
const topicosLoc = { en: TOPICOS_EN, es: TOPICOS_ES, fr: TOPICOS_FR, de: TOPICOS_DE, "zh-CN": TOPICOS_ZH }[locale];
return {
locale,
topicos: topicosLoc
? Object.fromEntries(topicosLoc.map((tp) => [tp.id, { nome: tp.nome, pinoRotulo: tp.pinoRotulo, termos: tp.termos }]))
: null,
itens: itens.map((item, i) => ({ id: i, ...item })),
series: montarConhecimento(seriesData, conexoes),
};