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
@@ -8,6 +8,8 @@ import CodeExample from "@/components/CodeExample";
|
||||
import frameworksDataPt from "@/public/frameworks.json";
|
||||
import frameworksDataEn from "@/data/en/frameworks.json";
|
||||
import frameworksDataEs from "@/data/es/frameworks.json";
|
||||
import frameworksDataFr from "@/data/fr/frameworks.json";
|
||||
import frameworksDataDe from "@/data/de/frameworks.json";
|
||||
import { getLocalizedHref } from "@/i18n/links";
|
||||
import { ArrowRight, ArrowUpRight, BookOpen, Box, Check, Code, Layers } from "lucide-react";
|
||||
|
||||
@@ -15,8 +17,10 @@ export default async function FrameworkDetail({ params }) {
|
||||
const { locale, key } = await params;
|
||||
const isEn = locale === "en";
|
||||
const isEs = locale === "es";
|
||||
const currentLocale = isEs ? "es" : isEn ? "en" : "pt";
|
||||
const frameworksData = isEs ? frameworksDataEs : isEn ? frameworksDataEn : frameworksDataPt;
|
||||
const isFr = locale === "fr";
|
||||
const isDe = locale === "de";
|
||||
const currentLocale = isEs ? "es" : isEn ? "en" : isFr ? "fr" : isDe ? "de" : "pt";
|
||||
const frameworksData = isEs ? frameworksDataEs : isEn ? frameworksDataEn : isFr ? frameworksDataFr : isDe ? frameworksDataDe : frameworksDataPt;
|
||||
const framework = frameworksData[key];
|
||||
|
||||
if (!framework) {
|
||||
@@ -38,7 +42,7 @@ export default async function FrameworkDetail({ params }) {
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(jsonLd.trilha([
|
||||
{ nome: isEs ? "Inicio" : isEn ? "Home" : "Início", caminho: isEs ? "/es" : isEn ? "/en" : "/" },
|
||||
{ nome: isEs ? "Inicio" : isEn ? "Home" : isFr ? "Accueil" : isDe ? "Startseite" : "Início", caminho: isEs ? "/es" : isEn ? "/en" : isFr ? "/fr" : isDe ? "/de" : "/" },
|
||||
{ nome: "Frameworks", caminho: getLocalizedHref("/frameworks", currentLocale) },
|
||||
{ nome: framework.nome, caminho: getLocalizedHref(`/frameworks/${encodeURIComponent(key)}`, currentLocale) },
|
||||
])),
|
||||
@@ -51,7 +55,9 @@ export default async function FrameworkDetail({ params }) {
|
||||
<PageHero
|
||||
isEn={isEn}
|
||||
isEs={isEs}
|
||||
trail={[{ label: isEs ? "Frameworks y SDKs" : isEn ? "Frameworks & SDKs" : "Frameworks e SDKs", href: getLocalizedHref("/frameworks", currentLocale) }, { label: framework.nome }]}
|
||||
isFr={isFr}
|
||||
isDe={isDe}
|
||||
trail={[{ label: isEs ? "Frameworks y SDKs" : isEn ? "Frameworks & SDKs" : isFr ? "Frameworks et SDKs" : isDe ? "Frameworks & SDKs" : "Frameworks e SDKs", href: getLocalizedHref("/frameworks", currentLocale) }, { label: framework.nome }]}
|
||||
icon={Layers}
|
||||
label={framework.tipo}
|
||||
title={framework.nome}
|
||||
@@ -60,41 +66,41 @@ export default async function FrameworkDetail({ params }) {
|
||||
{framework.documentacao && (
|
||||
<a href={framework.documentacao} target="_blank" rel="noopener noreferrer" className="btn btn-primary">
|
||||
<BookOpen className="h-4 w-4" aria-hidden="true" />
|
||||
{isEs ? "Documentación oficial" : isEn ? "Official documentation" : "Documentação oficial"}
|
||||
{isEs ? "Documentación oficial" : isEn ? "Official documentation" : isFr ? "Documentation officielle" : isDe ? "Offizielle Dokumentation" : "Documentação oficial"}
|
||||
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
)}
|
||||
{framework.repositorio && (
|
||||
<a href={framework.repositorio} target="_blank" rel="noopener noreferrer" className="btn btn-ghost">
|
||||
<Code className="h-4 w-4" aria-hidden="true" />
|
||||
{isEs ? "Repositorio en GitHub" : isEn ? "GitHub repository" : "Repositório no GitHub"}
|
||||
{isEs ? "Repositorio en GitHub" : isEn ? "GitHub repository" : isFr ? "Dépôt sur GitHub" : isDe ? "GitHub-Repository" : "Repositório no GitHub"}
|
||||
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
)}
|
||||
</PageHero>
|
||||
|
||||
<section className="shell mt-10" aria-label={isEs ? "Resumen" : isEn ? "Summary" : "Resumo"}>
|
||||
<section className="shell mt-10" aria-label={isEs ? "Resumen" : isEn ? "Summary" : isFr ? "Résumé" : isDe ? "Übersicht" : "Resumo"}>
|
||||
<dl className="grid gap-3 md:grid-cols-3">
|
||||
<div className="tile">
|
||||
<dt className="text-xs font-medium text-muted">{isEs ? "Lenguaje" : isEn ? "Language" : "Linguagem"}</dt>
|
||||
<dt className="text-xs font-medium text-muted">{isEs ? "Lenguaje" : isEn ? "Language" : isFr ? "Langage" : isDe ? "Sprache" : "Linguagem"}</dt>
|
||||
<dd className="mt-1 font-display text-2xl font-semibold tracking-[-0.03em] text-ink">{framework.linguagem}</dd>
|
||||
<dd className="mt-0.5 text-xs text-muted">{framework.nome_completo}</dd>
|
||||
</div>
|
||||
<div className="tile">
|
||||
<dt className="text-xs font-medium text-muted">{isEs ? "Categoría" : isEn ? "Category" : "Categoria"}</dt>
|
||||
<dt className="text-xs font-medium text-muted">{isEs ? "Categoría" : isEn ? "Category" : isFr ? "Catégorie" : isDe ? "Kategorie" : "Categoria"}</dt>
|
||||
<dd className="mt-1 font-display text-2xl font-semibold tracking-[-0.03em] text-ink">{framework.tipo}</dd>
|
||||
</div>
|
||||
<div className="tile">
|
||||
<dt className="text-xs font-medium text-muted">{isEs ? "Objetivo principal" : isEn ? "Main purpose" : "Objetivo principal"}</dt>
|
||||
<dt className="text-xs font-medium text-muted">{isEs ? "Objetivo principal" : isEn ? "Main purpose" : isFr ? "Objectif principal" : isDe ? "Hauptzweck" : "Objetivo principal"}</dt>
|
||||
<dd className="mt-1 text-sm font-medium leading-relaxed text-ink">{framework.funcao_principal}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</section>
|
||||
|
||||
<section className="shell mt-12 grid gap-5 lg:grid-cols-2" aria-label={isEs ? "Funciones y aplicaciones" : isEn ? "Features and applications" : "Recursos e aplicações"}>
|
||||
<section className="shell mt-12 grid gap-5 lg:grid-cols-2" aria-label={isEs ? "Funciones y aplicaciones" : isEn ? "Features and applications" : isFr ? "Fonctionnalités et applications" : isDe ? "Features und Anwendungen" : "Recursos e aplicações"}>
|
||||
<div className="card p-5 sm:p-7">
|
||||
<h2 className="font-display text-xl font-semibold tracking-[-0.03em] text-ink">
|
||||
{isEs ? "Funciones destacadas" : isEn ? "Key features" : "Recursos de destaque"}
|
||||
{isEs ? "Funciones destacadas" : isEn ? "Key features" : isFr ? "Fonctionnalités clés" : isDe ? "Wichtigste Features" : "Recursos de destaque"}
|
||||
</h2>
|
||||
<ul className="mt-5 space-y-3">
|
||||
{features.map((feature) => (
|
||||
@@ -108,7 +114,7 @@ export default async function FrameworkDetail({ params }) {
|
||||
|
||||
<div className="card p-5 sm:p-7">
|
||||
<h2 className="font-display text-xl font-semibold tracking-[-0.03em] text-ink">
|
||||
{isEs ? "Cuándo usar" : isEn ? "When to use" : "Quando usar"}
|
||||
{isEs ? "Cuándo usar" : isEn ? "When to use" : isFr ? "Quand l'utiliser" : isDe ? "Einsatzbereiche" : "Quando usar"}
|
||||
</h2>
|
||||
<ul className="mt-5 space-y-2.5">
|
||||
{useCases.map((useCase) => (
|
||||
@@ -126,10 +132,10 @@ export default async function FrameworkDetail({ params }) {
|
||||
<div className="max-w-2xl">
|
||||
<span className="chip chip-accent">
|
||||
<Box className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
{isEs ? "ESP-IDF 4.4 o superior" : isEn ? "ESP-IDF 4.4 or higher" : "ESP-IDF 4.4 ou superior"}
|
||||
{isEs ? "ESP-IDF 4.4 o superior" : isEn ? "ESP-IDF 4.4 or higher" : isFr ? "ESP-IDF 4.4 ou supérieur" : isDe ? "ESP-IDF 4.4 oder höher" : "ESP-IDF 4.4 ou superior"}
|
||||
</span>
|
||||
<h2 className="section-title mt-4">
|
||||
{isEs ? "Módulos con ESP Component Registry" : isEn ? "Modules with the ESP Component Registry" : "Módulos com o ESP Component Registry"}
|
||||
{isEs ? "Módulos con ESP Component Registry" : isEn ? "Modules with the ESP Component Registry" : isFr ? "Modules avec l'ESP Component Registry" : isDe ? "Module mit der ESP Component Registry" : "Módulos com o ESP Component Registry"}
|
||||
</h2>
|
||||
<p className="mt-3 text-base leading-relaxed text-muted">
|
||||
{isEs ? (
|
||||
@@ -144,6 +150,18 @@ export default async function FrameworkDetail({ params }) {
|
||||
<code className="rounded bg-surface-2 px-1.5 py-0.5 font-mono text-sm">idf_component.yml</code> and the command{" "}
|
||||
<code className="rounded bg-surface-2 px-1.5 py-0.5 font-mono text-sm">idf.py add-dependency</code> to download display drivers (LVGL), industrial stacks (Modbus), RainMaker, and more.
|
||||
</>
|
||||
) : isFr ? (
|
||||
<>
|
||||
Dans les projets ESP-IDF v4.4+ et v5.x, les bibliothèques n'ont plus besoin d'être ajoutées comme sous-modules Git. Utilisez le fichier{" "}
|
||||
<code className="rounded bg-surface-2 px-1.5 py-0.5 font-mono text-sm">idf_component.yml</code> et la commande{" "}
|
||||
<code className="rounded bg-surface-2 px-1.5 py-0.5 font-mono text-sm">idf.py add-dependency</code> pour télécharger des pilotes d'écran (LVGL), des piles industrielles (Modbus), RainMaker et bien plus encore.
|
||||
</>
|
||||
) : isDe ? (
|
||||
<>
|
||||
In Projekten mit ESP-IDF v4.4+ und v5.x müssen Bibliotheken nicht mehr als Git-Submodule eingebunden werden. Nutzen Sie{" "}
|
||||
<code className="rounded bg-surface-2 px-1.5 py-0.5 font-mono text-sm">idf_component.yml</code> und den Befehl{" "}
|
||||
<code className="rounded bg-surface-2 px-1.5 py-0.5 font-mono text-sm">idf.py add-dependency</code>, um Display-Treiber (LVGL), Industrieprotokolle (Modbus), RainMaker und mehr herunterzuladen.
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
Nos projetos ESP-IDF v4.4+ e v5.x, as bibliotecas não precisam mais entrar como submódulos Git. Use o{" "}
|
||||
@@ -154,7 +172,7 @@ export default async function FrameworkDetail({ params }) {
|
||||
</p>
|
||||
</div>
|
||||
<Link href={getLocalizedHref("/componentes", currentLocale)} className="btn btn-primary shrink-0">
|
||||
{isEs ? "Explorar componentes" : isEn ? "Explore components" : "Explorar componentes"}
|
||||
{isEs ? "Explorar componentes" : isEn ? "Explore components" : isFr ? "Explorer les composants" : isDe ? "Komponenten erkunden" : "Explorar componentes"}
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
@@ -170,7 +188,7 @@ export default async function FrameworkDetail({ params }) {
|
||||
<div className="shell section pt-10">
|
||||
<Link href={getLocalizedHref("/frameworks", currentLocale)} className="inline-flex min-h-11 items-center gap-2 text-sm font-medium text-accent hover:text-accent-strong">
|
||||
<ArrowRight className="h-4 w-4 rotate-180" aria-hidden="true" />
|
||||
{isEs ? "Ver todos los frameworks" : isEn ? "View all frameworks" : "Ver todos os frameworks"}
|
||||
{isEs ? "Ver todos los frameworks" : isEn ? "View all frameworks" : isFr ? "Voir tous les frameworks" : isDe ? "Alle Frameworks ansehen" : "Ver todos os frameworks"}
|
||||
</Link>
|
||||
</div>
|
||||
</main>
|
||||
@@ -184,21 +202,27 @@ export async function generateMetadata({ params }) {
|
||||
const { locale, key } = await params;
|
||||
const isEn = locale === "en";
|
||||
const isEs = locale === "es";
|
||||
const currentLocale = isEs ? "es" : isEn ? "en" : "pt";
|
||||
const frameworksData = isEs ? frameworksDataEs : isEn ? frameworksDataEn : frameworksDataPt;
|
||||
const isFr = locale === "fr";
|
||||
const isDe = locale === "de";
|
||||
const currentLocale = isEs ? "es" : isEn ? "en" : isFr ? "fr" : isDe ? "de" : "pt";
|
||||
const frameworksData = isEs ? frameworksDataEs : isEn ? frameworksDataEn : isFr ? frameworksDataFr : isDe ? frameworksDataDe : frameworksDataPt;
|
||||
const framework = frameworksData[key];
|
||||
|
||||
if (!framework) {
|
||||
return { title: isEs ? "Framework no encontrado" : isEn ? "Framework not found" : "Framework não encontrado", robots: { index: false, follow: false } };
|
||||
return { title: isEs ? "Framework no encontrado" : isEn ? "Framework not found" : isFr ? "Framework introuvable" : isDe ? "Framework nicht gefunden" : "Framework não encontrado", robots: { index: false, follow: false } };
|
||||
}
|
||||
|
||||
return {
|
||||
...paginaMeta({
|
||||
titulo: isEs ? `${framework.nome} para ESP32 · Guía técnica` : isEn ? `${framework.nome} for ESP32 · Technical Guide` : `${framework.nome} para ESP32 · Guia Técnico`,
|
||||
titulo: isEs ? `${framework.nome} para ESP32 · Guía técnica` : isEn ? `${framework.nome} for ESP32 · Technical Guide` : isFr ? `${framework.nome} pour ESP32 · Guide technique` : isDe ? `${framework.nome} für ESP32 · Technischer Leitfaden` : `${framework.nome} para ESP32 · Guia Técnico`,
|
||||
descricao: isEs
|
||||
? `${framework.nome_completo}: ${framework.descricao} Guía con ejemplos prácticos de código y casos de uso.`
|
||||
: isEn
|
||||
? `${framework.nome_completo}: ${framework.descricao} Guide with practical code examples and use cases.`
|
||||
: isFr
|
||||
? `${framework.nome_completo} : ${framework.descricao} Guide avec exemples pratiques de code et cas d'usage.`
|
||||
: isDe
|
||||
? `${framework.nome_completo}: ${framework.descricao} Leitfaden mit praktischen Codebeispielen und Anwendungsfällen.`
|
||||
: `${framework.nome_completo}: ${framework.descricao} Guia com exemplos práticos de código e casos de uso.`,
|
||||
caminho: `/frameworks/${encodeURIComponent(key)}`,
|
||||
tipo: "article",
|
||||
@@ -215,6 +239,18 @@ export async function generateMetadata({ params }) {
|
||||
`${framework.nome} ESP32`, `program ESP32 with ${framework.nome}`,
|
||||
"ESP32", "ESP32 framework",
|
||||
]
|
||||
: isFr
|
||||
? [
|
||||
framework.nome, framework.nome_completo,
|
||||
`${framework.nome} ESP32`, `programmer ESP32 avec ${framework.nome}`,
|
||||
"ESP32", "framework ESP32",
|
||||
]
|
||||
: isDe
|
||||
? [
|
||||
framework.nome, framework.nome_completo,
|
||||
`${framework.nome} ESP32`, `ESP32 programmieren mit ${framework.nome}`,
|
||||
"ESP32", "ESP32 Framework",
|
||||
]
|
||||
: [
|
||||
framework.nome, framework.nome_completo,
|
||||
`${framework.nome} ESP32`, `programar ESP32 com ${framework.nome}`,
|
||||
|
||||
@@ -4,17 +4,27 @@ 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
|
||||
? "Frameworks y SDKs para ESP32: Guía completa y comparativa"
|
||||
: isEn
|
||||
? "ESP32 Frameworks & SDKs: Complete Guide and Comparison"
|
||||
: isFr
|
||||
? "Frameworks et SDKs pour ESP32 : guide complet et comparatif"
|
||||
: isDe
|
||||
? "ESP32-Frameworks & SDKs: Vollständiger Leitfaden und Vergleich"
|
||||
: "Frameworks & SDKs para ESP32: Guia Completo e Comparativo",
|
||||
descricao: isEs
|
||||
? "Guía completa de desarrollo: ESP-IDF, ESP-RainMaker, ESP-Matter, Rust, ESP-ADF, ESP-SR, ESP-WHO, Arduino y MicroPython con ejemplos de código."
|
||||
: isEn
|
||||
? "Complete development guide: ESP-IDF, ESP-RainMaker, ESP-Matter, Rust, ESP-ADF, ESP-SR, ESP-WHO, Arduino, and MicroPython with code examples."
|
||||
: isFr
|
||||
? "Guide complet de développement : ESP-IDF, ESP-RainMaker, ESP-Matter, Rust, ESP-ADF, ESP-SR, ESP-WHO, Arduino et MicroPython avec exemples de code."
|
||||
: isDe
|
||||
? "Vollständiger Entwicklungsleitfaden: ESP-IDF, ESP-RainMaker, ESP-Matter, Rust, ESP-ADF, ESP-SR, ESP-WHO, Arduino und MicroPython mit Codebeispielen."
|
||||
: "Guia completo de desenvolvimento: ESP-IDF, ESP-RainMaker, ESP-Matter, Rust, ESP-ADF, ESP-SR, ESP-WHO, Arduino e MicroPython com exemplos de código.",
|
||||
caminho: "/frameworks",
|
||||
locale,
|
||||
@@ -46,6 +56,34 @@ export async function generateMetadata({ params }) {
|
||||
"frameworks ESP32",
|
||||
"program ESP32",
|
||||
]
|
||||
: isFr
|
||||
? [
|
||||
"ESP-IDF",
|
||||
"ESP-RainMaker",
|
||||
"ESP-Matter",
|
||||
"Rust ESP32",
|
||||
"ESP-SR",
|
||||
"ESP-ADF",
|
||||
"ESP-IoT-Solution",
|
||||
"Arduino ESP32",
|
||||
"MicroPython ESP32",
|
||||
"frameworks ESP32",
|
||||
"programmer ESP32",
|
||||
]
|
||||
: isDe
|
||||
? [
|
||||
"ESP-IDF",
|
||||
"ESP-RainMaker",
|
||||
"ESP-Matter",
|
||||
"Rust ESP32",
|
||||
"ESP-SR",
|
||||
"ESP-ADF",
|
||||
"ESP-IoT-Solution",
|
||||
"Arduino ESP32",
|
||||
"MicroPython ESP32",
|
||||
"ESP32 Frameworks",
|
||||
"ESP32 programmieren",
|
||||
]
|
||||
: [
|
||||
"ESP-IDF",
|
||||
"ESP-RainMaker",
|
||||
@@ -67,6 +105,8 @@ export default async function FrameworksLayout({ children, params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
const isEs = locale === "es";
|
||||
const isFr = locale === "fr";
|
||||
const isDe = locale === "de";
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
@@ -74,8 +114,8 @@ export default async function FrameworksLayout({ children, params }) {
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(
|
||||
jsonLd.trilha([
|
||||
{ nome: isEs ? "Inicio" : isEn ? "Home" : "Início", caminho: isEs ? "/es" : isEn ? "/en" : "/" },
|
||||
{ nome: "Frameworks", caminho: isEs ? "/es/frameworks" : isEn ? "/en/frameworks" : "/frameworks" },
|
||||
{ nome: isEs ? "Inicio" : isEn ? "Home" : isFr ? "Accueil" : isDe ? "Startseite" : "Início", caminho: isEs ? "/es" : isEn ? "/en" : isFr ? "/fr" : isDe ? "/de" : "/" },
|
||||
{ nome: "Frameworks", caminho: isEs ? "/es/frameworks" : isEn ? "/en/frameworks" : isFr ? "/fr/frameworks" : isDe ? "/de/frameworks" : "/frameworks" },
|
||||
])
|
||||
),
|
||||
}}
|
||||
|
||||
@@ -6,6 +6,8 @@ import Link from "next/link";
|
||||
import frameworksDataPt from "@/public/frameworks.json";
|
||||
import frameworksDataEn from "@/data/en/frameworks.json";
|
||||
import frameworksDataEs from "@/data/es/frameworks.json";
|
||||
import frameworksDataFr from "@/data/fr/frameworks.json";
|
||||
import frameworksDataDe from "@/data/de/frameworks.json";
|
||||
import { paginaMeta } from "@/lib/seo";
|
||||
import { getLocalizedHref } from "@/i18n/links";
|
||||
import { ArrowRight, ArrowUpRight, Box, Brain, Cloud, GraduationCap, Layers, Mic, Music, Sparkles } from "lucide-react";
|
||||
@@ -109,14 +111,82 @@ const GUIAS_ES = [
|
||||
},
|
||||
];
|
||||
|
||||
const GUIAS_FR = [
|
||||
{
|
||||
icon: GraduationCap,
|
||||
titulo: "Je débute",
|
||||
texto: "Arduino ou MicroPython sont les voies les plus rapides pour tester capteurs et APIs. Pour la production, optez pour ESP-IDF ou Rust.",
|
||||
links: [
|
||||
["Arduino", "/frameworks/Arduino"],
|
||||
["MicroPython", "/frameworks/MicroPython"],
|
||||
["Rust", "/frameworks/Rust-ESP"],
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: Cloud,
|
||||
titulo: "Cloud et maison connectée",
|
||||
texto: "ESP-Matter pour l'interopérabilité, ESP-RainMaker pour un cloud clé en main et Zigbee pour les réseaux maillés locaux à basse consommation.",
|
||||
links: [
|
||||
["RainMaker", "/frameworks/ESP-RainMaker"],
|
||||
["Matter", "/frameworks/ESP-Matter"],
|
||||
["Zigbee", "/frameworks/ESP-Zigbee-SDK"],
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: Sparkles,
|
||||
titulo: "Audio, voix et IA",
|
||||
texto: "ESP-ADF pour le traitement audio, ESP-SR pour la reconnaissance vocale hors ligne et ESP-NN pour accélérer le TinyML.",
|
||||
links: [
|
||||
["Audio", "/frameworks/ESP-ADF", Music],
|
||||
["Voix", "/frameworks/ESP-SR", Mic],
|
||||
["IA", "/frameworks/ESP-NN", Brain],
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const GUIAS_DE = [
|
||||
{
|
||||
icon: GraduationCap,
|
||||
titulo: "Erste Schritte",
|
||||
texto: "Arduino oder MicroPython sind die schnellsten Wege, um Sensoren und APIs zu testen. Für den Produkteinsatz empfehlen sich ESP-IDF oder Rust.",
|
||||
links: [
|
||||
["Arduino", "/frameworks/Arduino"],
|
||||
["MicroPython", "/frameworks/MicroPython"],
|
||||
["Rust", "/frameworks/Rust-ESP"],
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: Cloud,
|
||||
titulo: "Cloud und Smart Home",
|
||||
texto: "ESP-Matter für Interoperabilität, ESP-RainMaker für eine fertige Cloud-Lösung und Zigbee für stromsparende lokale Mesh-Netzwerke.",
|
||||
links: [
|
||||
["RainMaker", "/frameworks/ESP-RainMaker"],
|
||||
["Matter", "/frameworks/ESP-Matter"],
|
||||
["Zigbee", "/frameworks/ESP-Zigbee-SDK"],
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: Sparkles,
|
||||
titulo: "Audio, Sprache und KI",
|
||||
texto: "ESP-ADF für Audioverarbeitung, ESP-SR für Offline-Sprachkennung und ESP-NN zur Beschleunigung von TinyML.",
|
||||
links: [
|
||||
["Audio", "/frameworks/ESP-ADF", Music],
|
||||
["Sprache", "/frameworks/ESP-SR", Mic],
|
||||
["KI", "/frameworks/ESP-NN", Brain],
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export default async function Frameworks({ params }) {
|
||||
const { locale } = await params;
|
||||
const isEn = locale === "en";
|
||||
const isEs = locale === "es";
|
||||
const currentLocale = isEs ? "es" : isEn ? "en" : "pt";
|
||||
const frameworksData = isEs ? frameworksDataEs : isEn ? frameworksDataEn : frameworksDataPt;
|
||||
const isFr = locale === "fr";
|
||||
const isDe = locale === "de";
|
||||
const currentLocale = isEs ? "es" : isEn ? "en" : isFr ? "fr" : isDe ? "de" : "pt";
|
||||
const frameworksData = isEs ? frameworksDataEs : isEn ? frameworksDataEn : isFr ? frameworksDataFr : isDe ? frameworksDataDe : frameworksDataPt;
|
||||
const frameworks = Object.entries(frameworksData);
|
||||
const guias = isEs ? GUIAS_ES : isEn ? GUIAS_EN : GUIAS_PT;
|
||||
const guias = isEs ? GUIAS_ES : isEn ? GUIAS_EN : isFr ? GUIAS_FR : isDe ? GUIAS_DE : GUIAS_PT;
|
||||
|
||||
return (
|
||||
<div className="site-canvas min-h-screen">
|
||||
@@ -126,20 +196,26 @@ export default async function Frameworks({ params }) {
|
||||
<PageHero
|
||||
isEn={isEn}
|
||||
isEs={isEs}
|
||||
trail={[{ label: isEs ? "Frameworks y SDKs" : isEn ? "Frameworks & SDKs" : "Frameworks e SDKs" }]}
|
||||
isFr={isFr}
|
||||
isDe={isDe}
|
||||
trail={[{ label: isEs ? "Frameworks y SDKs" : isEn ? "Frameworks & SDKs" : isFr ? "Frameworks et SDKs" : isDe ? "Frameworks & SDKs" : "Frameworks e SDKs" }]}
|
||||
icon={Layers}
|
||||
label={isEs ? `${frameworks.length} frameworks y SDKs` : isEn ? `${frameworks.length} frameworks and SDKs` : `${frameworks.length} frameworks e SDKs`}
|
||||
title={isEs ? "Frameworks y SDKs de ESP32" : isEn ? "ESP32 Frameworks and SDKs" : "Frameworks e SDKs do ESP32"}
|
||||
label={isEs ? `${frameworks.length} frameworks y SDKs` : isEn ? `${frameworks.length} frameworks and SDKs` : isFr ? `${frameworks.length} frameworks et SDKs` : isDe ? `${frameworks.length} Frameworks und SDKs` : `${frameworks.length} frameworks e SDKs`}
|
||||
title={isEs ? "Frameworks y SDKs de ESP32" : isEn ? "ESP32 Frameworks and SDKs" : isFr ? "Frameworks et SDKs pour ESP32" : isDe ? "ESP32-Frameworks und SDKs" : "Frameworks e SDKs do ESP32"}
|
||||
lede={
|
||||
isEs
|
||||
? "Desde C/C++ nativo con FreeRTOS hasta Rust, nube IoT, reconocimiento de voz, audio y Matter. Elija según lo que desee construir."
|
||||
: isEn
|
||||
? "From native C/C++ with FreeRTOS to Rust, IoT cloud, speech recognition, audio, and Matter. Choose by what you want to build."
|
||||
: isFr
|
||||
? "Du C/C++ natif avec FreeRTOS à Rust, en passant par le cloud IoT, la reconnaissance vocale, l'audio et Matter. Choisissez selon ce que vous souhaitez concevoir."
|
||||
: isDe
|
||||
? "Von nativem C/C++ mit FreeRTOS bis hin zu Rust, IoT-Cloud, Spracherkennung, Audio und Matter. Wählen Sie passend zu Ihrem Projekt."
|
||||
: "Do C/C++ nativo com FreeRTOS ao Rust, passando por nuvem IoT, reconhecimento de voz, áudio e Matter. Escolha pelo que você quer construir."
|
||||
}
|
||||
/>
|
||||
|
||||
<section className="shell pt-10 sm:pt-12" aria-label={isEs ? "Por dónde empezar" : isEn ? "Where to begin" : "Por onde começar"}>
|
||||
<section className="shell pt-10 sm:pt-12" aria-label={isEs ? "Por dónde empezar" : isEn ? "Where to begin" : isFr ? "Par où commencer" : isDe ? "Wo anfangen" : "Por onde começar"}>
|
||||
<div className="grid gap-4 md:grid-cols-3">
|
||||
{guias.map(({ icon: Icon, titulo, texto, links }) => (
|
||||
<div key={titulo} className="card flex flex-col p-5 sm:p-6">
|
||||
@@ -168,7 +244,7 @@ export default async function Frameworks({ params }) {
|
||||
<div className="max-w-2xl">
|
||||
<span className="chip chip-accent">
|
||||
<Box className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
{isEs ? "Arquitectura modular" : isEn ? "Modular architecture" : "Arquitetura modular"}
|
||||
{isEs ? "Arquitectura modular" : isEn ? "Modular architecture" : isFr ? "Architecture modulaire" : isDe ? "Modulare Architektur" : "Arquitetura modular"}
|
||||
</span>
|
||||
<h2 className="section-title mt-4">ESP Component Registry</h2>
|
||||
<p className="mt-3 text-base leading-relaxed text-muted">
|
||||
@@ -182,6 +258,16 @@ export default async function Frameworks({ params }) {
|
||||
Install display drivers (LVGL), industrial stacks (Modbus), cloud integrations, and board support packages
|
||||
(BSPs) with a single line in your <code className="rounded bg-surface-2 px-1.5 py-0.5 font-mono text-sm">idf_component.yml</code> manifest.
|
||||
</>
|
||||
) : isFr ? (
|
||||
<>
|
||||
Installez des pilotes d'écran (LVGL), des piles industrielles (Modbus), des fonctionnalités cloud et des paquets de support de cartes
|
||||
(BSPs) avec une seule ligne dans votre manifeste <code className="rounded bg-surface-2 px-1.5 py-0.5 font-mono text-sm">idf_component.yml</code>.
|
||||
</>
|
||||
) : isDe ? (
|
||||
<>
|
||||
Installieren Sie Display-Treiber (LVGL), Industrieprotokolle (Modbus), Cloud-Funktionen und Board-Support-Pakete
|
||||
(BSPs) mit einer einzigen Zeile in Ihrem <code className="rounded bg-surface-2 px-1.5 py-0.5 font-mono text-sm">idf_component.yml</code>-Manifest.
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
Instale drivers de display (LVGL), pilhas industriais (Modbus), recursos de nuvem e pacotes de placa
|
||||
@@ -191,7 +277,7 @@ export default async function Frameworks({ params }) {
|
||||
</p>
|
||||
</div>
|
||||
<Link href={getLocalizedHref("/componentes", currentLocale)} className="btn btn-primary shrink-0">
|
||||
{isEs ? "Explorar componentes" : isEn ? "Explore components" : "Explorar componentes"}
|
||||
{isEs ? "Explorar componentes" : isEn ? "Explore components" : isFr ? "Explorer les composants" : isDe ? "Komponenten erkunden" : "Explorar componentes"}
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
@@ -201,8 +287,8 @@ export default async function Frameworks({ params }) {
|
||||
<SectionHead
|
||||
id="todos-titulo"
|
||||
eyebrow={isEs ? "Todos" : isEn ? "All" : "Todos"}
|
||||
title={isEs ? "Todos los frameworks" : isEn ? "All frameworks" : "Todos os frameworks"}
|
||||
lede={isEs ? "Cada ficha ofrece funciones, aplicaciones ideales, ejemplos de código y enlaces oficiales." : isEn ? "Each page provides features, ideal use cases, code examples, and official links." : "Cada ficha traz recursos, aplicações ideais, exemplo de código e links oficiais."}
|
||||
title={isEs ? "Todos los frameworks" : isEn ? "All frameworks" : isFr ? "Tous les frameworks" : isDe ? "Alle Frameworks" : "Todos os frameworks"}
|
||||
lede={isEs ? "Cada ficha ofrece funciones, aplicaciones ideales, ejemplos de código y enlaces oficiales." : isEn ? "Each page provides features, ideal use cases, code examples, and official links." : isFr ? "Chaque fiche présente les fonctionnalités, les cas d'usage idéaux, des exemples de code et les liens officiels." : isDe ? "Jedes Datenblatt bietet Features, ideale Anwendungsbereiche, Codebeispiele und offizielle Links." : "Cada ficha traz recursos, aplicações ideais, exemplo de código e links oficiais."}
|
||||
/>
|
||||
|
||||
<div className="mt-8 grid gap-4 md:grid-cols-2 lg:grid-cols-3">
|
||||
@@ -224,7 +310,7 @@ export default async function Frameworks({ params }) {
|
||||
</ul>
|
||||
|
||||
<span className="mt-5 inline-flex items-center gap-1 border-t border-line pt-4 text-sm font-medium text-accent">
|
||||
{isEs ? "Ver detalles y ejemplo" : isEn ? "View details and example" : "Ver detalhes e exemplo"}
|
||||
{isEs ? "Ver detalles y ejemplo" : isEn ? "View details and example" : isFr ? "Voir les détails et l'exemple" : isDe ? "Details und Beispiel ansehen" : "Ver detalhes e exemplo"}
|
||||
<ArrowUpRight className="h-4 w-4 transition-transform group-hover:-translate-y-0.5 group-hover:translate-x-0.5" aria-hidden="true" />
|
||||
</span>
|
||||
</Link>
|
||||
|
||||
Reference in new issue
Block a user