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

+37 -31
View File
@@ -97,9 +97,10 @@ export const jsonLd = {
const isEs = locale === "es";
const isFr = locale === "fr";
const isDe = locale === "de";
const orgAnchor = isEn ? "organization" : isEs ? "organizacion" : (isFr || isDe) ? "organisation" : "organizacao";
const isZh = locale === "zh-CN";
const orgAnchor = isZh ? "organization" : isEn ? "organization" : isEs ? "organizacion" : (isFr || isDe) ? "organisation" : "organizacao";
const authorAnchor = isEn ? "author" : isFr ? "auteur" : "autor";
const inLang = isEn ? "en" : isEs ? "es-419" : isFr ? "fr" : isDe ? "de" : "pt-BR";
const inLang = isEn ? "en" : isEs ? "es-419" : isFr ? "fr" : isZh ? "zh-CN" : isDe ? "de" : "pt-BR";
return {
"@context": "https://schema.org",
"@graph": [
@@ -115,7 +116,7 @@ export const jsonLd = {
? "Documentación del ecosistema ESP32: especificaciones, patillaje, comparación y selección de series."
: isFr
? "Documentation de l'écosystème ESP32 : spécifications, brochages, comparaison et sélection de séries."
: isDe
: isZh ? "ESP32 生态文档(简体中文):规格、引脚、对比与系列选型。" : isDe
? "Dokumentation des ESP32-Ökosystems: Spezifikationen, Pinbelegung, Vergleich und Serienauswahl."
: "Documentação do ecossistema ESP32 em português brasileiro: especificações, pinagem, comparação e seleção de séries.",
publisher: { "@id": `${SITE.url}/#${orgAnchor}` },
@@ -166,33 +167,34 @@ export const jsonLd = {
const isEs = locale === "es";
const isFr = locale === "fr";
const isDe = locale === "de";
const isZh = locale === "zh-CN";
const prop = (nome, valor) =>
valor ? { "@type": "PropertyValue", name: nome, value: String(valor) } : null;
const propriedades = [
prop(isEn ? "Manufacturer" : isEs ? "Fabricante" : isFr ? "Fabricant" : isDe ? "Hersteller" : "Fabricante", "Espressif Systems"),
prop(isEn ? "Architecture" : isEs ? "Arquitectura" : isFr ? "Architecture" : isDe ? "Architektur" : "Arquitetura"),
prop(isEn ? "Cores" : isEs ? "Núcleos" : isFr ? "Cœurs" : isDe ? "Kerne" : "Núcleos", serie.nucleos),
prop(isEn ? "Max frequency" : isEs ? "Frecuencia máxima" : isFr ? "Fréquence maximale" : isDe ? "Maximale Frequenz" : "Frequência máxima", serie.frequencia),
prop(isEn ? "Manufacturer" : isEs ? "Fabricante" : isFr ? "Fabricant" : isZh ? "制造商" : isDe ? "Hersteller" : "Fabricante", "Espressif Systems"),
prop(isEn ? "Architecture" : isEs ? "Arquitectura" : isFr ? "Architecture" : isZh ? "架构" : isDe ? "Architektur" : "Arquitetura"),
prop(isEn ? "Cores" : isEs ? "Núcleos" : isFr ? "Cœurs" : isZh ? "内核数" : isDe ? "Kerne" : "Núcleos", serie.nucleos),
prop(isEn ? "Max frequency" : isEs ? "Frecuencia máxima" : isFr ? "Fréquence maximale" : isZh ? "最高频率" : isDe ? "Maximale Frequenz" : "Frequência máxima", serie.frequencia),
prop("SRAM", serie.memoria_sram),
prop("RTC SRAM", serie.memoria_sram_rtc),
prop(isEn ? "Supported Flash" : isEs ? "Flash soportada" : isFr ? "Flash prise en charge" : isDe ? "Unterstützter Flash" : "Flash suportada", serie.flash_suportada),
prop(isEn ? "Supported PSRAM" : isEs ? "PSRAM soportada" : isFr ? "PSRAM prise en charge" : isDe ? "Unterstütztes PSRAM" : "PSRAM suportada", serie.psram_suportada),
prop(isEn ? "Supported Flash" : isEs ? "Flash soportada" : isFr ? "Flash prise en charge" : isZh ? "支持的闪存" : isDe ? "Unterstützter Flash" : "Flash suportada", serie.flash_suportada),
prop(isEn ? "Supported PSRAM" : isEs ? "PSRAM soportada" : isFr ? "PSRAM prise en charge" : isZh ? "支持的 PSRAM" : isDe ? "Unterstütztes PSRAM" : "PSRAM suportada", serie.psram_suportada),
prop("GPIO", serie.gpio),
prop("Wi-Fi", serie.wifi),
prop("Bluetooth", serie.bluetooth),
prop("Zigbee / Thread / 802.15.4", serie.zigbee_thread),
prop(isEn ? "Package" : isEs ? "Encapsulado" : isFr ? "Boîtier" : isDe ? "Gehäuse" : "Encapsulamento", serie.encapsulamento),
prop(isEn ? "Minimum ESP-IDF" : isEs ? "ESP-IDF mínimo" : isFr ? "ESP-IDF minimum" : isDe ? "Mindestens ESP-IDF" : "ESP-IDF mínimo", serie.esp_idf_minimo),
prop(isEn ? "Package" : isEs ? "Encapsulado" : isFr ? "Boîtier" : isZh ? "封装" : isDe ? "Gehäuse" : "Encapsulamento", serie.encapsulamento),
prop(isEn ? "Minimum ESP-IDF" : isEs ? "ESP-IDF mínimo" : isFr ? "ESP-IDF minimum" : isZh ? "最低 ESP-IDF 版本" : isDe ? "Mindestens ESP-IDF" : "ESP-IDF mínimo", serie.esp_idf_minimo),
].filter(Boolean);
const imagem = serie.placa
? `${SITE.url}${serie.placa}`
: `${SITE.url}/opengraph-image.png`;
const basePath = isDe ? `/de/serien/${chave}` : isFr ? `/fr/series/${chave}` : isEn ? `/en/series/${chave}` : isEs ? `/es/series/${chave}` : `/series/${chave}`;
const anchor = isEn ? "article" : isEs ? "articulo" : isFr ? "article" : isDe ? "artikel" : "artigo";
const inLang = isEn ? "en" : isEs ? "es-419" : isFr ? "fr" : isDe ? "de" : "pt-BR";
const basePath = isZh ? `/zh-CN/series/${chave}` : isDe ? `/de/serien/${chave}` : isFr ? `/fr/series/${chave}` : isEn ? `/en/series/${chave}` : isEs ? `/es/series/${chave}` : `/series/${chave}`;
const anchor = isEn ? "article" : isEs ? "articulo" : isFr ? "article" : isZh ? "article" : isDe ? "artikel" : "artigo";
const inLang = isEn ? "en" : isEs ? "es-419" : isFr ? "fr" : isZh ? "zh-CN" : isDe ? "de" : "pt-BR";
return {
"@context": "https://schema.org",
@@ -204,7 +206,7 @@ export const jsonLd = {
? `${serie.nome_completo || chave}: especificaciones y patillaje`
: isFr
? `${serie.nome_completo || chave} : spécifications et brochage`
: isDe
: isZh ? `${serie.nome_completo || chave}:规格与引脚图` : isDe
? `${serie.nome_completo || chave}: Spezifikationen und Pinbelegung`
: `${serie.nome_completo || chave}: especificações e pinagem`,
name: isEn
@@ -213,7 +215,7 @@ export const jsonLd = {
? `${serie.nome_completo || chave} - Documentación técnica y especificaciones`
: isFr
? `${serie.nome_completo || chave} - Documentation technique et spécifications`
: isDe
: isZh ? `${serie.nome_completo || chave} - 技术文档与规格` : isDe
? `${serie.nome_completo || chave} - Technische Dokumentation und Spezifikationen`
: `${serie.nome_completo || chave} - Documentação Técnica e Especificações`,
description: serie.descricao,
@@ -254,9 +256,10 @@ export const jsonLd = {
const isEs = locale === "es";
const isFr = locale === "fr";
const isDe = locale === "de";
const basePath = isDe ? `/de/frameworks/${encodeURIComponent(chave)}` : isFr ? `/fr/frameworks/${encodeURIComponent(chave)}` : isEn ? `/en/frameworks/${encodeURIComponent(chave)}` : isEs ? `/es/frameworks/${encodeURIComponent(chave)}` : `/frameworks/${encodeURIComponent(chave)}`;
const anchor = isEn ? "article" : isEs ? "articulo" : isFr ? "article" : isDe ? "artikel" : "artigo";
const inLang = isEn ? "en" : isEs ? "es-419" : isFr ? "fr" : isDe ? "de" : "pt-BR";
const isZh = locale === "zh-CN";
const basePath = isZh ? `/zh-CN/frameworks/${encodeURIComponent(chave)}` : isDe ? `/de/frameworks/${encodeURIComponent(chave)}` : isFr ? `/fr/frameworks/${encodeURIComponent(chave)}` : isEn ? `/en/frameworks/${encodeURIComponent(chave)}` : isEs ? `/es/frameworks/${encodeURIComponent(chave)}` : `/frameworks/${encodeURIComponent(chave)}`;
const anchor = isEn ? "article" : isEs ? "articulo" : isFr ? "article" : isZh ? "article" : isDe ? "artikel" : "artigo";
const inLang = isEn ? "en" : isEs ? "es-419" : isFr ? "fr" : isZh ? "zh-CN" : isDe ? "de" : "pt-BR";
return {
"@context": "https://schema.org",
"@type": "TechArticle",
@@ -267,14 +270,14 @@ export const jsonLd = {
? `${framework.nome} para ESP32: Guía y documentación`
: isFr
? `${framework.nome} pour ESP32 : Guide et documentation`
: isDe
: isZh ? `用于 ESP32 的 ${framework.nome}:指南与文档` : isDe
? `${framework.nome} für ESP32: Leitfaden und Dokumentation`
: `${framework.nome} para ESP32: Guia e Documentação`,
name: isEn
? `${framework.nome_completo || framework.nome} for ESP32`
: isFr
? `${framework.nome_completo || framework.nome} pour ESP32`
: isDe
: isZh ? `用于 ESP32 的 ${framework.nome_completo || framework.nome}` : isDe
? `${framework.nome_completo || framework.nome} für ESP32`
: `${framework.nome_completo || framework.nome} para ESP32`,
description: framework.descricao,
@@ -317,14 +320,15 @@ export const jsonLd = {
const isEs = locale === "es";
const isFr = locale === "fr";
const isDe = locale === "de";
const basePath = isDe ? "/de/glossar" : isFr ? "/fr/glossaire" : isEn ? "/en/glossary" : isEs ? "/es/glosario" : "/glossario";
const anchor = isDe ? "glossar" : isFr ? "glossaire" : isEn ? "glossary" : isEs ? "glosario" : "glossario";
const inLang = isEn ? "en" : isEs ? "es-419" : isFr ? "fr" : isDe ? "de" : "pt-BR";
const isZh = locale === "zh-CN";
const basePath = isZh ? "/zh-CN/glossary" : isDe ? "/de/glossar" : isFr ? "/fr/glossaire" : isEn ? "/en/glossary" : isEs ? "/es/glosario" : "/glossario";
const anchor = isZh ? "glossary" : isDe ? "glossar" : isFr ? "glossaire" : isEn ? "glossary" : isEs ? "glosario" : "glossario";
const inLang = isEn ? "en" : isEs ? "es-419" : isFr ? "fr" : isZh ? "zh-CN" : isDe ? "de" : "pt-BR";
return {
"@context": "https://schema.org",
"@type": "DefinedTermSet",
"@id": `${SITE.url}${basePath}#${anchor}`,
name: isEn ? "ESP32 Technical Glossary" : isEs ? "Glosario técnico de ESP32" : isFr ? "Glossaire technique de l'ESP32" : isDe ? "Technisches Glossar für ESP32" : "Glossário Técnico do ESP32",
name: isEn ? "ESP32 Technical Glossary" : isEs ? "Glosario técnico de ESP32" : isFr ? "Glossaire technique de l'ESP32" : isZh ? "ESP32 技术术语表" : isDe ? "Technisches Glossar für ESP32" : "Glossário Técnico do ESP32",
inLanguage: inLang,
hasDefinedTerm: categorias.flatMap((cat) =>
cat.termos.map((t) => ({
@@ -356,7 +360,8 @@ export const jsonLd = {
const isEs = locale === "es";
const isFr = locale === "fr";
const isDe = locale === "de";
const inLang = isEn ? "en" : isEs ? "es-419" : isFr ? "fr" : isDe ? "de" : "pt-BR";
const isZh = locale === "zh-CN";
const inLang = isEn ? "en" : isEs ? "es-419" : isFr ? "fr" : isZh ? "zh-CN" : isDe ? "de" : "pt-BR";
return {
"@context": "https://schema.org",
"@type": "WebApplication",
@@ -452,21 +457,22 @@ export const jsonLd = {
const isEs = locale === "es";
const isFr = locale === "fr";
const isDe = locale === "de";
const basePath = isDe ? "/de/ueber-uns" : isFr ? "/fr/a-propos" : isEn ? "/en/about" : isEs ? "/es/acerca" : "/sobre";
const anchor = isDe ? "ueber-uns" : isFr ? "a-propos" : isEn ? "about" : isEs ? "acerca" : "sobre";
const inLang = isEn ? "en" : isEs ? "es-419" : isFr ? "fr" : isDe ? "de" : "pt-BR";
const isZh = locale === "zh-CN";
const basePath = isZh ? "/zh-CN/about" : isDe ? "/de/ueber-uns" : isFr ? "/fr/a-propos" : isEn ? "/en/about" : isEs ? "/es/acerca" : "/sobre";
const anchor = isZh ? "about" : isDe ? "ueber-uns" : isFr ? "a-propos" : isEn ? "about" : isEs ? "acerca" : "sobre";
const inLang = isEn ? "en" : isEs ? "es-419" : isFr ? "fr" : isZh ? "zh-CN" : isDe ? "de" : "pt-BR";
return {
"@context": "https://schema.org",
"@type": "AboutPage",
"@id": `${SITE.url}${basePath}#${anchor}`,
name: isEn ? "About ESPDocs" : isEs ? "Acerca de ESPDocs" : isFr ? "À propos d'ESPDocs" : isDe ? "Über ESPDocs" : "Sobre o ESPDocs",
name: isEn ? "About ESPDocs" : isEs ? "Acerca de ESPDocs" : isFr ? "À propos d'ESPDocs" : isZh ? "关于 ESPDocs" : isDe ? "Über ESPDocs" : "Sobre o ESPDocs",
description: isEn
? "ESPDocs is an independent platform organizing technical documentation of the ESP32 ecosystem."
: isEs
? "ESPDocs es una plataforma independiente que reúne la documentación técnica del ecosistema ESP32."
: isFr
? "ESPDocs est une plateforme indépendante qui rassemble la documentation technique de l'écosystème ESP32."
: isDe
: isZh ? "ESPDocs 是一个独立平台,汇集 ESP32 生态的文档,使用简体中文。" : isDe
? "ESPDocs ist eine unabhängige Plattform, die die technische Dokumentation des ESP32-Ökosystems zusammenführt."
: "O ESPDocs é uma plataforma independente que reúne a documentação do ecossistema ESP32 em português brasileiro.",
url: `${SITE.url}${basePath}`,