feat(i18n): French and German localization (phase 5)
- Add full message catalogs and content for French (fr) and German (de) - Implement ASCII canonical slugs for French and German routes - Add language-specific search endpoints (/api/busca/fr, /api/busca/de) - Configure strict 404 responses for /fr/livro and /de/livro - Localize SEO, OpenGraph (fr_FR, de_DE), Twitter and JSON-LD schemas - Add localized code example comments across 14 examples for fr and de - Enable 'fr' and 'de' in ENABLED_LOCALES with root negotiation and redirect - Extend test suite in check-i18n, smoke-imagem and verifica-vazamentos Co-Authored-By: Antigravity <noreply@google.com>
This commit is contained in:
1 parent
7b673aeb4b
commit
7fce46b9e1
104 files changed
+33369
-686
No files matched your search
+116
-26
@@ -12,15 +12,33 @@ export async function generateMetadata({ params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
const isEs = locale === "es";
|
||||
const isFr = locale === "fr";
|
||||
const isDe = locale === "de";
|
||||
return paginaMeta({
|
||||
titulo: isEs ? "Acerca del proyecto" : isEn ? "About the Project" : "Sobre o projeto",
|
||||
descricao: isEs
|
||||
titulo: isDe
|
||||
? "Über das Projekt"
|
||||
: isFr
|
||||
? "À propos du projet"
|
||||
: isEs
|
||||
? "Acerca del proyecto"
|
||||
: isEn
|
||||
? "About the Project"
|
||||
: "Sobre o projeto",
|
||||
descricao: isDe
|
||||
? "ESPDocs ist eine unabhängige Plattform, die die technische Dokumentation des ESP32-Ökosystems strukturiert. Erfahren Sie mehr über das Projekt und wie Sie beitragen können."
|
||||
: isFr
|
||||
? "ESPDocs est une plateforme indépendante qui organise la documentation technique de l'écosystème ESP32. Découvrez le projet et comment contribuer."
|
||||
: isEs
|
||||
? "ESPDocs es una plataforma independiente que organiza la documentación técnica del ecosistema ESP32. Conozca el proyecto y cómo contribuir."
|
||||
: isEn
|
||||
? "ESPDocs is an independent platform organizing technical documentation of the ESP32 ecosystem. Learn about the project and how to contribute."
|
||||
: "O ESPDocs é uma plataforma independente que reúne a documentação do ecossistema ESP32 em português brasileiro. Saiba como o projeto nasceu e como contribuir.",
|
||||
caminho: "/sobre",
|
||||
keywords: isEs
|
||||
keywords: isDe
|
||||
? ["ESPDocs", "ESP32 Dokumentation", "ESP32 Open-Source-Projekt", "Open Source"]
|
||||
: isFr
|
||||
? ["ESPDocs", "documentation ESP32", "projet open source ESP32", "open source"]
|
||||
: isEs
|
||||
? ["ESPDocs", "documentación ESP32", "proyecto open source ESP32", "código abierto"]
|
||||
: isEn
|
||||
? ["ESPDocs", "ESP32 documentation", "open source ESP32 project"]
|
||||
@@ -34,6 +52,8 @@ export default async function Sobre({ params }) {
|
||||
const isPt = locale === "pt";
|
||||
const isEn = locale === "en";
|
||||
const isEs = locale === "es";
|
||||
const isFr = locale === "fr";
|
||||
const isDe = locale === "de";
|
||||
|
||||
const featuresPt = [
|
||||
{ icon: Languages, title: "Em português", desc: "Dados técnicos organizados e apresentados em português do Brasil." },
|
||||
@@ -56,7 +76,21 @@ export default async function Sobre({ params }) {
|
||||
{ icon: Code, title: "Código abierto", desc: "Las contribuciones son bienvenidas en Gitea." },
|
||||
];
|
||||
|
||||
const features = isEs ? featuresEs : isEn ? featuresEn : featuresPt;
|
||||
const featuresFr = [
|
||||
{ icon: Languages, title: "En français", desc: "Données techniques organisées et présentées clairement en français." },
|
||||
{ icon: GitCompare, title: "Comparaisons visuelles", desc: "Tableaux et schémas pour choisir la bonne série sans ouvrir dix datasheets." },
|
||||
{ icon: Globe, title: "Accès centralisé", desc: "Liens directs vers la documentation officielle, les dépôts et les exemples." },
|
||||
{ icon: Code, title: "Open source", desc: "Les contributions sont les bienvenues sur Gitea." },
|
||||
];
|
||||
|
||||
const featuresDe = [
|
||||
{ icon: Languages, title: "Auf Deutsch", desc: "Technische Daten übersichtlich und strukturiert auf Deutsch aufbereitet." },
|
||||
{ icon: GitCompare, title: "Visuelle Vergleiche", desc: "Tabellen und Diagramme zur Auswahl der richtigen Serie, ohne zehn Datenblätter zu öffnen." },
|
||||
{ icon: Globe, title: "Zentraler Zugang", desc: "Direkte Links zu offizieller Dokumentation, Repositories und Beispielen." },
|
||||
{ icon: Code, title: "Open Source", desc: "Beiträge sind auf Gitea herzlich willkommen." },
|
||||
];
|
||||
|
||||
const features = isDe ? featuresDe : isFr ? featuresFr : isEs ? featuresEs : isEn ? featuresEn : featuresPt;
|
||||
|
||||
return (
|
||||
<div className="site-canvas min-h-screen">
|
||||
@@ -70,8 +104,8 @@ export default async function Sobre({ params }) {
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.trilha([
|
||||
{ nome: isEs ? "Inicio" : isPt ? "Início" : "Home", caminho: isEn ? "/en" : isEs ? "/es" : "/" },
|
||||
{ nome: isEs ? "Acerca del proyecto" : isPt ? "Sobre o Projeto" : "About the Project", caminho: isEn ? "/en/about" : isEs ? "/es/acerca" : "/sobre" },
|
||||
{ nome: isDe ? "Startseite" : isFr ? "Accueil" : isEs ? "Inicio" : isPt ? "Início" : "Home", caminho: isDe ? "/de" : isFr ? "/fr" : isEn ? "/en" : isEs ? "/es" : "/" },
|
||||
{ nome: isDe ? "Über das Projekt" : isFr ? "À propos du projet" : isEs ? "Acerca del proyecto" : isPt ? "Sobre o Projeto" : "About the Project", caminho: isDe ? "/de/ueber-uns" : isFr ? "/fr/a-propos" : isEn ? "/en/about" : isEs ? "/es/acerca" : "/sobre" },
|
||||
])
|
||||
),
|
||||
}}
|
||||
@@ -83,12 +117,18 @@ export default async function Sobre({ params }) {
|
||||
<PageHero
|
||||
isEn={isEn}
|
||||
isEs={isEs}
|
||||
trail={[{ label: isEs ? "Acerca" : isPt ? "Sobre" : "About" }]}
|
||||
isFr={isFr}
|
||||
isDe={isDe}
|
||||
trail={[{ label: isDe ? "Über uns" : isFr ? "À propos" : isEs ? "Acerca" : isPt ? "Sobre" : "About" }]}
|
||||
icon={Info}
|
||||
label={isEs ? "Proyecto independiente" : isPt ? "Projeto independente" : "Independent project"}
|
||||
title={isEs ? "Acerca de ESPDocs" : isPt ? "Sobre o ESPDocs" : "About ESPDocs"}
|
||||
label={isDe ? "Unabhängiges Projekt" : isFr ? "Projet indépendant" : isEs ? "Proyecto independiente" : isPt ? "Projeto independente" : "Independent project"}
|
||||
title={isDe ? "Über ESPDocs" : isFr ? "À propos d'ESPDocs" : isEs ? "Acerca de ESPDocs" : isPt ? "Sobre o ESPDocs" : "About ESPDocs"}
|
||||
lede={
|
||||
isEs
|
||||
isDe
|
||||
? "Eine inoffizielle deutschsprachige Plattform, die technische Informationen zum ESP32 strukturiert und Sie mit der offiziellen Dokumentation von Espressif verbindet. Entwickelt für die Open-Hardware-Community."
|
||||
: isFr
|
||||
? "Une plateforme non officielle en français qui organise les informations techniques de l'ESP32 et vous oriente vers la documentation officielle d'Espressif. Conçue pour la communauté du matériel libre."
|
||||
: isEs
|
||||
? "Una plataforma no oficial, en español, que organiza la información técnica del ESP32 y le conecta con la documentación oficial de Espressif. Creada para la comunidad de hardware abierto."
|
||||
: isPt
|
||||
? "Uma plataforma não oficial, em português, que organiza as informações técnicas do ESP32 e leva você à documentação oficial da Espressif. Feita para a comunidade de hardware livre."
|
||||
@@ -97,7 +137,7 @@ export default async function Sobre({ params }) {
|
||||
>
|
||||
<a href={REPOSITORIO} target="_blank" rel="noopener noreferrer" className="btn btn-primary">
|
||||
<GiteaMark className="h-4 w-4" />
|
||||
{isEs ? "Ver el repositorio" : isPt ? "Ver o repositório" : "View repository"}
|
||||
{isDe ? "Repository ansehen" : isFr ? "Voir le dépôt" : isEs ? "Ver el repositorio" : isPt ? "Ver o repositório" : "View repository"}
|
||||
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
</PageHero>
|
||||
@@ -105,9 +145,13 @@ export default async function Sobre({ params }) {
|
||||
<div className="shell section grid grid-cols-1 gap-10 pt-12 sm:pt-16 lg:grid-cols-[1fr_22rem] lg:gap-14">
|
||||
<div className="min-w-0 max-w-3xl space-y-12">
|
||||
<section aria-labelledby="missao">
|
||||
<h2 id="missao" className="section-title">{isEs ? "Misión" : isPt ? "Missão" : "Mission"}</h2>
|
||||
<h2 id="missao" className="section-title">{isDe ? "Mission" : isFr ? "Mission" : isEs ? "Misión" : isPt ? "Missão" : "Mission"}</h2>
|
||||
<p className="mt-4 text-base leading-relaxed text-muted">
|
||||
{isEs
|
||||
{isDe
|
||||
? "Den Zugang zum und das Verständnis für das ESP32-Ökosystem durch eine deutsche Oberfläche erleichtern, die Spezifikationen bündelt, Serien vergleicht, Frameworks vorstellt und offizielle Dokumentationslinks zentralisiert. Ziel ist es, Entwicklungszeit bei Firmware und IoT-Projekten zu sparen."
|
||||
: isFr
|
||||
? "Faciliter l'accès et la compréhension de l'écosystème ESP32 avec une interface en français qui organise les spécifications, compare les séries, présente les frameworks et centralise les liens vers la documentation officielle. L'objectif est de vous faire gagner du temps dans le développement de firmware et d'IoT."
|
||||
: isEs
|
||||
? "Facilitar el acceso y la comprensión del ecosistema ESP32 con una interfaz en español que organiza especificaciones, compara series, presenta frameworks y centraliza los enlaces a la documentación oficial. El objetivo es ahorrar tiempo en el desarrollo de firmware e IoT."
|
||||
: isPt
|
||||
? "Facilitar o acesso e a compreensão do ecossistema ESP32 com uma interface em português que organiza especificações, compara séries, apresenta frameworks e centraliza os links da documentação oficial. O objetivo é economizar o seu tempo no desenvolvimento de firmware e IoT."
|
||||
@@ -116,9 +160,13 @@ export default async function Sobre({ params }) {
|
||||
</section>
|
||||
|
||||
<section aria-labelledby="porque">
|
||||
<h2 id="porque" className="section-title">{isEs ? "¿Por qué existe ESPDocs?" : isPt ? "Por que o ESPDocs existe" : "Why ESPDocs exists"}</h2>
|
||||
<h2 id="porque" className="section-title">{isDe ? "Warum es ESPDocs gibt" : isFr ? "Pourquoi ESPDocs existe" : isEs ? "¿Por qué existe ESPDocs?" : isPt ? "Por que o ESPDocs existe" : "Why ESPDocs exists"}</h2>
|
||||
<p className="mt-4 text-base leading-relaxed text-muted">
|
||||
{isEs
|
||||
{isDe
|
||||
? "Informationen über den ESP32 sind oft über dichte Datenblätter, technische Referenzhandbücher (TRM) und sekundäre Repositories verstreut. ESPDocs verdichtet und strukturiert diese Daten für eine schnelle Vorabauswahl, bevor Sie tiefer in die offizielle Technik einsteigen."
|
||||
: isFr
|
||||
? "Les informations sur l'ESP32 sont souvent dispersées entre des fiches techniques denses, des manuels de référence technique (TRM) et des dépôts secondaires. ESPDocs condense et structure ces données pour une évaluation rapide avant d'approfondir l'ingénierie officielle."
|
||||
: isEs
|
||||
? "La información sobre el ESP32 suele estar dispersa entre hojas de datos densas, manuales de referencia técnica (TRM) y repositorios secundarios. ESPDocs condensa y estructura estos datos para una evaluación rápida antes de profundizar en la ingeniería oficial."
|
||||
: isPt
|
||||
? "As informações sobre os ESP32 costumam estar espalhadas entre datasheets densos, manuais de referência (TRM) e repositórios secundários, tudo em inglês. O ESPDocs condensa e estrutura esses dados para a triagem rápida, antes de você aprofundar na engenharia oficial."
|
||||
@@ -140,16 +188,32 @@ export default async function Sobre({ params }) {
|
||||
</section>
|
||||
|
||||
<section aria-labelledby="contribuir">
|
||||
<h2 id="contribuir" className="section-title">{isEs ? "Cómo contribuir" : isPt ? "Como contribuir" : "How to contribute"}</h2>
|
||||
<h2 id="contribuir" className="section-title">{isDe ? "Wie Sie beitragen können" : isFr ? "Comment contribuer" : isEs ? "Cómo contribuir" : isPt ? "Como contribuir" : "How to contribute"}</h2>
|
||||
<p className="mt-4 text-base leading-relaxed text-muted">
|
||||
{isEs
|
||||
{isDe
|
||||
? "Übersetzungskorrekturen, Tabellenanpassungen und neue Codebeispiele sind herzlich willkommen. Das Projekt wächst gemeinsam mit der Community."
|
||||
: isFr
|
||||
? "Les corrections de traduction, les ajustements de tableaux et les nouveaux exemples de code sont très appréciés. Le projet grandit avec la communauté."
|
||||
: isEs
|
||||
? "Las correcciones de traducción, ajustes en tablas y nuevos ejemplos de código son muy bienvenidos. El proyecto crece junto con la comunidad."
|
||||
: isPt
|
||||
? "Correções de tradução, ajustes em tabelas e novos exemplos de código são muito bem-vindos. O projeto cresce com a comunidade."
|
||||
: "Translation fixes, table refinements and new code examples are welcome. The project grows with the community."}
|
||||
</p>
|
||||
<ol className="mt-6 space-y-3">
|
||||
{(isEs
|
||||
{(isDe
|
||||
? [
|
||||
"Erstellen Sie einen Fork des Repositories auf Gitea.",
|
||||
"Implementieren Sie die Verbesserungen und prüfen Sie die offiziellen technischen Referenzen.",
|
||||
"Eröffnen Sie einen Pull Request mit einer Beschreibung der vorgenommenen Änderungen.",
|
||||
]
|
||||
: isFr
|
||||
? [
|
||||
"Forkez le dépôt sur Gitea.",
|
||||
"Apportez les améliorations et vérifiez les références techniques officielles.",
|
||||
"Ouvrez une Pull Request décrivant les modifications apportées.",
|
||||
]
|
||||
: isEs
|
||||
? [
|
||||
"Haga un fork del repositorio en Gitea.",
|
||||
"Implemente las mejoras y verifique las referencias técnicas oficiales.",
|
||||
@@ -178,9 +242,13 @@ export default async function Sobre({ params }) {
|
||||
</section>
|
||||
|
||||
<section aria-labelledby="acessibilidade">
|
||||
<h2 id="acessibilidade" className="section-title">{isEs ? "Accesibilidad" : isPt ? "Acessibilidade" : "Accessibility"}</h2>
|
||||
<h2 id="acessibilidade" className="section-title">{isDe ? "Barrierefreiheit" : isFr ? "Accessibilité" : isEs ? "Accesibilidad" : isPt ? "Acessibilidade" : "Accessibility"}</h2>
|
||||
<p className="mt-4 text-base leading-relaxed text-muted">
|
||||
{isEs
|
||||
{isDe
|
||||
? "ESPDocs legt großen Wert auf Lesbarkeit, hohen Kontrast (WCAG-Stufe AAA) und vollständige Tastaturnavigation. Wenn Sie auf Lese- oder Navigationsbarrieren stoßen, eröffnen Sie bitte ein Issue im Repository."
|
||||
: isFr
|
||||
? "ESPDocs privilégie la lisibilité, un contraste élevé (niveau AAA du WCAG) et une navigation complète au clavier. Si vous rencontrez un obstacle de lecture ou de navigation, ouvrez un ticket dans le dépôt."
|
||||
: isEs
|
||||
? "ESPDocs prioriza la legibilidad, el alto contraste (nivel AAA de WCAG) y la navegación completa por teclado. Si encuentra alguna barrera de lectura o navegación, abra un issue en el repositorio."
|
||||
: isPt
|
||||
? "O ESPDocs prioriza a legibilidade, o contraste alto (nível AAA da WCAG) e a navegação completa por teclado. Se encontrar alguma barreira de leitura ou navegação, abra uma issue no repositório."
|
||||
@@ -189,7 +257,7 @@ export default async function Sobre({ params }) {
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<aside className="space-y-5 lg:sticky lg:top-28 lg:self-start" aria-label={isEs ? "Autor y aviso legal" : isPt ? "Autor e aviso legal" : "Author and legal notice"}>
|
||||
<aside className="space-y-5 lg:sticky lg:top-28 lg:self-start" aria-label={isDe ? "Autor und rechtlicher Hinweis" : isFr ? "Auteur et mentions légales" : isEs ? "Autor y aviso legal" : isPt ? "Autor e aviso legal" : "Author and legal notice"}>
|
||||
<div className="panel p-6 sm:p-7">
|
||||
<div className="flex items-center gap-4">
|
||||
<span className="grid h-16 w-16 shrink-0 place-items-center rounded-2xl border border-line bg-white">
|
||||
@@ -197,11 +265,29 @@ export default async function Sobre({ params }) {
|
||||
</span>
|
||||
<div>
|
||||
<h2 className="font-display text-lg font-semibold text-ink">Lucas Rayan Guerra</h2>
|
||||
<p className="text-sm text-muted">{isEs ? "Creador de Ciência Embarcada" : isPt ? "Criador do Ciência Embarcada" : "Creator of Ciência Embarcada"}</p>
|
||||
<p className="text-sm text-muted">{isDe ? "Gründer von Ciência Embarcada" : isFr ? "Créateur de Ciência Embarcada" : isEs ? "Creador de Ciência Embarcada" : isPt ? "Criador do Ciência Embarcada" : "Creator of Ciência Embarcada"}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-5 space-y-3 text-sm leading-relaxed text-muted">
|
||||
{isEs ? (
|
||||
{isDe ? (
|
||||
<>
|
||||
<p>
|
||||
Systementwicklungstechniker, Informatikstudent an der UFRPE und Forscher im Bereich Blockchain und Kryptographie.
|
||||
</p>
|
||||
<p>
|
||||
Software-Direktor bei Semine AgriTech und Referent bei Veranstaltungen wie REC'n'Play, der Inhalte zu Hardware, IoT und Cybersicherheit vermittelt.
|
||||
</p>
|
||||
</>
|
||||
) : isFr ? (
|
||||
<>
|
||||
<p>
|
||||
Technicien en développement de systèmes, étudiant en informatique à l'UFRPE et chercheur en blockchain et cryptographie.
|
||||
</p>
|
||||
<p>
|
||||
Directeur logiciel chez Semine AgriTech et conférencier lors d'événements comme REC'n'Play, partageant des connaissances sur le matériel, l'IoT et la cybersécurité.
|
||||
</p>
|
||||
</>
|
||||
) : isEs ? (
|
||||
<>
|
||||
<p>
|
||||
Técnico en Desarrollo de Sistemas, estudiante de Ciencias de la Computación en la UFRPE e investigador en Blockchain y Criptografía.
|
||||
@@ -233,15 +319,19 @@ export default async function Sobre({ params }) {
|
||||
)}
|
||||
</div>
|
||||
<a href="https://cienciaembarcada.com.br" target="_blank" rel="noopener noreferrer" className="btn btn-ghost mt-6 w-full">
|
||||
{isEs ? "Visitar Ciência Embarcada" : isPt ? "Visitar o Ciência Embarcada" : "Visit Ciência Embarcada"}
|
||||
{isDe ? "Ciência Embarcada besuchen" : isFr ? "Visiter Ciência Embarcada" : isEs ? "Visitar Ciência Embarcada" : isPt ? "Visitar o Ciência Embarcada" : "Visit Ciência Embarcada"}
|
||||
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="callout callout-warn">
|
||||
<p className="font-semibold text-ink">{isEs ? "Aviso legal" : isPt ? "Aviso legal" : "Legal notice"}</p>
|
||||
<p className="font-semibold text-ink">{isDe ? "Rechtlicher Hinweis" : isFr ? "Mentions légales" : isEs ? "Aviso legal" : isPt ? "Aviso legal" : "Legal notice"}</p>
|
||||
<p className="mt-1">
|
||||
{isEs
|
||||
{isDe
|
||||
? "ESPDocs ist ein Aggregator und Kurator. Die referenzierten Handbücher und Repositories sind Eigentum von Espressif Systems. Konsultieren Sie bei geschäftskritischen oder kommerziellen Projekten stets die offizielle Dokumentation."
|
||||
: isFr
|
||||
? "ESPDocs est une plateforme d'agrégation et de synthèse. Les manuels et dépôts référencés appartiennent à Espressif Systems. Pour les projets critiques ou commerciaux, consultez systématiquement la documentation officielle."
|
||||
: isEs
|
||||
? "ESPDocs es un agregador y organizador. Los manuales y repositorios referenciados pertenecen a Espressif Systems. En proyectos críticos o comerciales, consulte siempre la documentación oficial."
|
||||
: isPt
|
||||
? "O ESPDocs é um agregador e organizador. Os manuais e repositórios referenciados pertencem à Espressif Systems. Em projetos críticos ou comerciais, consulte sempre a documentação oficial."
|
||||
|
||||
Reference in new issue
Block a user