diff --git a/docs/contribute/translating.md b/docs/contribute/translating.md new file mode 100644 index 000000000000..81596ba60b11 --- /dev/null +++ b/docs/contribute/translating.md @@ -0,0 +1,261 @@ +--- +id: translating +title: Translating the Docs +sidebar_label: Translating Docs +--- + +This page covers how translation is **wired into the site**: what the config +does, where files go, and the build behaviour that will bite you. It does not +cover how to translate a page — that is the `translate` skill in +`.agents/skills/translate.md`, and the vocabulary rules live in `glossary.yml` +and `translation-rules.yml`. + +Keep it that way. If you find yourself writing a terminology rule here, it +belongs in `glossary.yml` instead. + +| Where | What it decides | +| ----------------------------- | ------------------------------------------- | +| `.agents/skills/translate.md` | How a page gets translated, and when | +| `glossary.yml` | Which terms stay in English | +| `translation-rules.yml` | Locale phrasing, register, punctuation | +| `AGENTS.md` | Order of work, house style, what to edit | +| This page | How the site is built and served per locale | + +English is always the source of truth. Translated content lives under +`i18n//` and mirrors the English path. Anything not translated falls +back to the English page automatically, so partial coverage is a valid state — +no broken pages, no placeholders. + +:::tip Current status + +- `en` — source of truth, complete +- `es` — site chrome (navbar, footer, sidebar labels, homepage) plus **What is + OpenFn?**, **Try out v2**, **Key Concepts**, and **Get Help**. All four pages + were produced by the `translate` skill and are + `translation_review_status: machine`; none has been human-reviewed yet. +- `fr` — planned, not enabled + +::: + +## Enabling a locale + +`docusaurus.config.js` declares which locales exist: + +```js +i18n: { + defaultLocale: 'en', + locales: ['en', 'es'], + // ... +} +``` + +English is served from the site root (`/documentation/...`), Spanish from a +locale prefix (`/es/documentation/...`). A locale dropdown in the navbar +switches between them. + +**Enabling a locale is a human decision, not a translation step** — it changes +what gets built and deployed. The `translate` skill checks that the locale is +already enabled and stops if it is not. Adding French means editing +`i18n.locales` and `i18n.localeConfigs`, then running +`yarn docusaurus write-translations --locale fr`. + +## Where files go + +The path after `current/` must match the path after `docs/` exactly: + +| English source | Spanish translation | +| -------------------------- | -------------------------------------------------------------------- | +| `docs/get-started/home.md` | `i18n/es/docusaurus-plugin-content-docs/current/get-started/home.md` | +| `docs/get-help/support.md` | `i18n/es/docusaurus-plugin-content-docs/current/get-help/support.md` | + +`id` and `slug` in the front matter define the route, so they must stay +identical to the English page. `title` and `sidebar_label` get translated. The +`translation_*` keys are described in the `translate` skill; Docusaurus ignores +unknown front matter keys, so they are safe to add. + +## Three things that will break the build + +These are all real failures we hit enabling Spanish, and they only show up on +non-default locales — English keeps passing, which makes them confusing to +debug. + +### Link to docs with site-absolute paths, not relative `.md` paths + +This is already the house style in `AGENTS.md`, and i18n is why it matters. On +an English page, use: + +```md +[Key Concepts](/documentation/get-started/terminology) +``` + +not: + +```md +[Key Concepts](../get-started/terminology.md) +``` + +Relative `.md` links only resolve when both pages come from the same content +directory. Once one is translated and the other is not, they come from different +directories — one from `i18n/es/`, the other falling back from `docs/` — and +Docusaurus cannot resolve the path. With `onBrokenLinks` set to `throw`, that +fails the build. + +On a **translated** page, write the locale in: the `translate` skill asks for +`/es/documentation/get-started/terminology`, and that is what these pages do. +Links into the generated adaptor pages stay unprefixed, since those are English +only. + +Four such links were converted when Spanish was added. Roughly **100 relative +`.md` links remain across ~35 pages** in `docs/`, which are house-style +violations the `lint` skill should pick up section by section. They are harmless +while both ends are English, and become build failures the moment either end is +translated. + +### Translated headings need the English anchor + +A heading's anchor is a link target, so translating the text silently breaks +every link pointing at it. Pin the English anchor: + +```md +## Nuestros productos {#our-products} +``` + +Only headings whose text actually changes need this. Glossary product nouns that +stay in English (`## Work Order`, `## Run`) keep their anchors for free — the +whole of Key Concepts needed no pinning for exactly that reason. + +### Sidebar items need a unique `key` + +Docusaurus derives a sidebar item's translation key from its `key` if it has +one, and from its **label** otherwise, so two items sharing a label collide and +throw `Multiple docs sidebar items produce the same translation key`. + +`sidebars-adaptors.js` generates one category per adaptor, each with items +labelled `Functions`, `Configuration`, `Changelog`, `README.md` and `Overview` — +about 100 collisions per label. Every generated item now carries a key +namespaced by adaptor: + +```js +{ + type: 'doc', + label: 'Overview', + key: `${a.name}-overview`, + id: a.name, +} +``` + +If you add items to a generated sidebar, give them a unique `key`. + +## Interface strings + +Anything that is not markdown — navbar labels, footer columns, sidebar category +names, the homepage — lives in JSON. Do not hand-write those files; generate +them: + +```bash +yarn docusaurus write-translations --locale es +``` + +This writes new or missing keys into `i18n/es/` and **leaves existing +translations untouched**. Then fill in the `message` values: + +| File | What it covers | +| ---------------------------------------------- | ------------------------------------------- | +| `code.json` | Strings from React components (`src/pages`) | +| `docusaurus-theme-classic/navbar.json` | Navbar labels | +| `docusaurus-theme-classic/footer.json` | Footer columns and links | +| `docusaurus-plugin-content-docs/current.json` | Sidebar category labels, version label | +| `docusaurus-plugin-content-blog*/options.json` | Blog and Articles SEO titles | + +Two things worth knowing about these files: + +- **Only keep keys we actually own.** `@docusaurus/theme-translations` already + ships Spanish for the theme's own strings, so `code.json` holds our + `homepage.*` keys plus the handful of `theme.*` strings upstream has left in + English. Copying the rest would override upstream and go stale on upgrade. +- **Leave out anything computed.** The footer copyright is built from + `new Date().getFullYear()`, so translating it would freeze the year. It is + omitted deliberately and falls back to the source. + +:::warning After running write-translations, check your diff + +`write-translations` does not know which keys we deliberately left out. It will +re-add roughly 130 `theme.*` keys to `code.json` and the footer `copyright` key, +filled in with values it read from upstream. Committing those silently takes +over maintenance of strings Docusaurus already translates for us, and freezes +the copyright year. + +Keep only the keys you actually came to add. If `git diff` on `code.json` shows +more than the strings you were working on, you have picked up the inherited +ones. + +::: + +If you add user-facing copy to a React component, wrap it so it can be +extracted: + +```jsx +import Translate, { translate } from '@docusaurus/Translate'; + +

+ Newsletter +

; + +; +``` + +Always set an explicit `id`. Auto-generated ids are derived from the English +text, so they change whenever the English copy is edited and silently orphan the +translation. + +## Not translated, on purpose + +- **Adaptor docs** (`/adaptors/`) — generated from adaptor source repos, so + anything written here would be overwritten. +- **The job library** — same reason. +- **The v1.105 (legacy) docs** — frozen and being sunsetted. +- **Articles and blog posts** — long-form and frequently added. + +All of these fall back to English. + +## Known gaps + +**Search does not cover Spanish.** The site uses Algolia DocSearch with +`contextualSearch: true`, which scopes results to the language being browsed. +The crawler is only configured for the English site, so searching from a `/es/` +page returns nothing until the DocSearch crawler config is updated. Worth +resolving before the Spanish site is promoted anywhere. + +**Full builds are slower.** `yarn build` builds every locale, so build time +scales with the number of languages. + +## Running it locally + +For a quick look at a single locale, use the dev server: + +```bash +yarn start --locale es +``` + +:::danger `yarn build --locale es` is not a substitute for `yarn build` + +The two use different base URLs, and they disagree about locale-prefixed links. + +A full `yarn build` builds `es` as a sub-site at `baseUrl: /es/`, so its route +paths are `/es/documentation/...` and the `/es/`-prefixed links in translated +pages resolve. `yarn build --locale es` builds Spanish as though it were the +only language, at `baseUrl: /`, so its route paths are `/documentation/...` — +and every correctly written `/es/...` link in a translated page is reported as a +broken link. With `onBrokenLinks: throw`, the single-locale build fails on pages +the real build is perfectly happy with. + +So treat a `--locale` failure as suspect until you have reproduced it with a +full build, and always run plain `yarn build` before opening a PR. That is what +CI and the deploy workflow run. + +::: diff --git a/docs/get-help/support.md b/docs/get-help/support.md index df511222aa6d..2a73f0ecc831 100644 --- a/docs/get-help/support.md +++ b/docs/get-help/support.md @@ -3,15 +3,26 @@ title: Support for OpenFn Implementations sidebar_label: Get Help --- -## Ask the Community! -If you need help getting started, have questions, or product feedback, first check out our **[Community](https://community.openfn.org)**. Our core team and other OpenFn implementers monitor all posts to help each other out, share examples, and circulate product updates. +## Ask the Community! -## Have a question about your project on OpenFn.org? -If you're using the hosted OpenFn platform SaaS, and have a private question about your project, account, or billing, contact our core team at [support@openfn.org](mailto://support@openfn.org). +If you need help getting started, have questions, or product feedback, first +check out our **[Community](https://community.openfn.org)**. Our core team and +other OpenFn implementers monitor all posts to help each other out, share +examples, and circulate product updates. + +## Have a question about your project on OpenFn.org? + +If you're using the hosted OpenFn platform SaaS, and have a private question +about your project, account, or billing, contact our core team at +[support@openfn.org](mailto://support@openfn.org). ## Need helping hands? -The OpenFn core team and our certified partners offer enterprise support, implementation & developer services, and training to jump-start your team. Check out our website: + +The OpenFn core team and our certified partners offer enterprise support, +implementation & developer services, and training to jump-start your team. Check +out our website: + - About [OpenFn services & pricing](https://www.openfn.org/pricing) - About our [certified partners](https://www.openfn.org/partners) - \ No newline at end of file + diff --git a/docs/get-started/try-out.md b/docs/get-started/try-out.md index db9d1ffb1c65..23289e04c3ac 100644 --- a/docs/get-started/try-out.md +++ b/docs/get-started/try-out.md @@ -50,7 +50,7 @@ without limits. See our GitHub repo for developer docs: :::info Questions? Check out these docs for more details on specific features (see menu sidebar), -browse the [main docs page](./home.md), or post your questions on +browse the [main docs page](/documentation/), or post your questions on [Community](https://community.openfn.org). ::: diff --git a/docs/monitor-history/inspect-runs.md b/docs/monitor-history/inspect-runs.md index e63b28fa78e6..75d55e3d4785 100644 --- a/docs/monitor-history/inspect-runs.md +++ b/docs/monitor-history/inspect-runs.md @@ -3,7 +3,7 @@ title: Inspect Runs & Search via the History page sidebar_label: Inspect Runs --- -A [Run](../get-started/terminology.md#run) is created each time +A [Run](/documentation/get-started/terminology#run) is created each time OpenFn attempts to excute a Workflow for a given Work Order. All Runs can be viewed, filtered, and searched via the `History` page. diff --git a/docs/tutorials/commcare-to-db.md b/docs/tutorials/commcare-to-db.md index 57432a272d52..01d0f256d779 100644 --- a/docs/tutorials/commcare-to-db.md +++ b/docs/tutorials/commcare-to-db.md @@ -9,7 +9,7 @@ title: Syncing your CommCare form submissions to a PostgreSQL database minute!) - You have checked out our glossary and have an understanding of basic OpenFn and API terminology. Check out the pages below to get started - - [OpenFn Concepts](../get-started/terminology.md) + - [OpenFn Concepts](/documentation/get-started/terminology) - [A glossary for data integration](../get-started/glossary.md) - You have a CommCare application with at least one form configured. This is your source system. diff --git a/docs/tutorials/http-to-googlesheets.md b/docs/tutorials/http-to-googlesheets.md index ff1abea1c410..9fcaba5b66f4 100644 --- a/docs/tutorials/http-to-googlesheets.md +++ b/docs/tutorials/http-to-googlesheets.md @@ -21,7 +21,7 @@ Here are some we assume you've looked over before you begin this process. - You have checked out our glossary and have an understanding of basic OpenFn & API concepts. Check out the pages below to get started - - [OpenFn Concepts](../get-started/terminology.md) + - [OpenFn Concepts](/documentation/get-started/terminology) - [A glossary for data integration](../get-started/glossary.md) - You have a Google Account. We will use it to create a credential to authorize with Google Sheets. diff --git a/docusaurus.config.js b/docusaurus.config.js index fdf1a521f462..d67373e4e7c5 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -12,6 +12,30 @@ module.exports = { favicon: 'img/favicon.ico', organizationName: 'openfn', projectName: 'docs', + // --- i18n (internationalization) --- + // Proof of concept: English (default) + Spanish. + // Translated content lives in i18n//. Anything not translated + // falls back to the English source automatically. + // + // Local dev for a single locale (much faster than building everything): + // yarn start --locale es + // yarn build --locale es + i18n: { + defaultLocale: 'en', + locales: ['en', 'es'], + localeConfigs: { + en: { + label: 'English', + direction: 'ltr', + htmlLang: 'en', + }, + es: { + label: 'Español', + direction: 'ltr', + htmlLang: 'es', + }, + }, + }, markdown: { hooks: { onBrokenMarkdownLinks: 'warn' }, mermaid: true, @@ -71,6 +95,10 @@ module.exports = { label: 'Articles', position: 'left', }, + { + type: 'localeDropdown', + position: 'right', + }, { type: 'docsVersionDropdown', position: 'right', @@ -151,6 +179,9 @@ module.exports = { sidebarPath: require.resolve('./sidebars-main.js'), routeBasePath: '/documentation', editUrl: 'https://github.com/openfn/docs/edit/main', + // Point "Edit this page" at the translated file rather than the + // English source when reading a non-default locale. + editLocalizedFiles: true, lastVersion: 'current', versions: { current: { diff --git a/i18n/es/code.json b/i18n/es/code.json new file mode 100644 index 000000000000..91c5e2d5c0d7 --- /dev/null +++ b/i18n/es/code.json @@ -0,0 +1,126 @@ +{ + "homepage.highlights.jobWritingGuide.title": { + "message": "Guía para escribir Jobs" + }, + "homepage.highlights.jobWritingGuide.description": { + "message": "¿Vas a escribir un Job para OpenFn? Empieza por aquí" + }, + "homepage.highlights.cliUsage.title": { + "message": "Ejemplos de uso del CLI" + }, + "homepage.highlights.cliUsage.description": { + "message": "Descubre de un vistazo todo lo que puede hacer el CLI" + }, + "homepage.highlights.javascriptTips.title": { + "message": "Trucos y consejos de JavaScript" + }, + "homepage.highlights.javascriptTips.description": { + "message": "Mejora tu código" + }, + "homepage.highlights.heading": { + "message": "✨Destacados de la documentación✨" + }, + "homepage.features.docs.title": { + "message": "Documentación" + }, + "homepage.features.docs.description": { + "message": "Documentación sobre todos los aspectos de OpenFn, el principal bien público digital para la automatización de flujos de trabajo." + }, + "homepage.features.adaptors.title": { + "message": "Adaptors" + }, + "homepage.features.adaptors.description": { + "message": "Documentación, ejemplos, registros de cambios y descripciones generales de los Adaptors, con búsqueda y navegación, para conectar los bienes públicos digitales más usados del mundo." + }, + "homepage.features.articles.title": { + "message": "Artículos" + }, + "homepage.features.articles.description": { + "message": "¿Cómo prepararse para una integración de datos? ¿Cómo estructurar los IDs externos? ¿Cómo..." + }, + "homepage.features.blog.title": { + "message": "Blog" + }, + "homepage.features.blog.description": { + "message": "Ayudamos a que las iniciativas de impacto social más prometedoras del mundo alcancen escala mediante la automatización, la integración de datos y la interoperabilidad. Estas son sus historias." + }, + "homepage.features.enterprise.title": { + "message": "Empresas" + }, + "homepage.features.enterprise.description": { + "message": "Descubre la plataforma de integración como servicio (iPaaS) de OpenFn para empresas, con planes gratuitos permanentes y opciones accesibles para crecer." + }, + "homepage.meta.title": { + "message": "Inicio" + }, + "homepage.meta.description": { + "message": "El sitio de documentación de OpenFn" + }, + "homepage.hero.title": { + "message": "Documentación de OpenFn" + }, + "homepage.hero.subtitle": { + "message": "El principal bien público digital para la automatización de flujos de trabajo. OpenFn hace que las TIC para el desarrollo (ICT4D) sean más eficientes." + }, + "homepage.hero.cta": { + "message": "Comenzar" + }, + "homepage.newsletter.title": { + "message": "Boletín" + }, + "homepage.newsletter.imageAlt": { + "message": "Boletín" + }, + "homepage.newsletter.description": { + "message": "No te pierdas ninguna novedad: suscríbete aquí a nuestro boletín." + }, + "homepage.newsletter.emailPlaceholder": { + "message": "Correo electrónico" + }, + "homepage.newsletter.subscribe": { + "message": "Suscribirse" + }, + "theme.admonition.tip": { + "message": "consejo", + "description": "The default label used for the Tip admonition (:::tip)" + }, + "theme.admonition.info": { + "message": "información", + "description": "The default label used for the Info admonition (:::info)" + }, + "theme.docs.versionBadge.label": { + "message": "Versión: {versionLabel}" + }, + "theme.IconExternalLink.ariaLabel": { + "message": "(se abre en una pestaña nueva)", + "description": "The ARIA label for the external link icon" + }, + "theme.colorToggle.ariaLabel.mode.system": { + "message": "modo del sistema", + "description": "The name for the system color mode" + }, + "theme.navbar.mobileDropdown.collapseButton.expandAriaLabel": { + "message": "Expandir el menú desplegable", + "description": "The ARIA label of the button to expand the mobile dropdown navbar item" + }, + "theme.navbar.mobileDropdown.collapseButton.collapseAriaLabel": { + "message": "Contraer el menú desplegable", + "description": "The ARIA label of the button to collapse the mobile dropdown navbar item" + }, + "theme.blog.authorsList.pageTitle": { + "message": "Autores", + "description": "The title of the authors page" + }, + "theme.blog.author.noPosts": { + "message": "Este autor aún no ha escrito publicaciones.", + "description": "The text for authors with 0 blog post" + }, + "theme.contentVisibility.draftBanner.title": { + "message": "Página en borrador", + "description": "The draft content banner title" + }, + "theme.contentVisibility.draftBanner.message": { + "message": "Esta página es un borrador. Solo será visible en el entorno de desarrollo y se excluirá de la compilación de producción.", + "description": "The draft content banner message" + } +} diff --git a/i18n/es/docusaurus-plugin-content-blog-articles/options.json b/i18n/es/docusaurus-plugin-content-blog-articles/options.json new file mode 100644 index 000000000000..fabe0f18cf00 --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-blog-articles/options.json @@ -0,0 +1,14 @@ +{ + "title": { + "message": "Artículos", + "description": "The title for the blog used in SEO" + }, + "description": { + "message": "Artículos de ayuda de OpenFn", + "description": "The description for the blog used in SEO" + }, + "sidebar.title": { + "message": "Artículos recientes", + "description": "The label for the left sidebar" + } +} diff --git a/i18n/es/docusaurus-plugin-content-blog/options.json b/i18n/es/docusaurus-plugin-content-blog/options.json new file mode 100644 index 000000000000..18375b3a3f5a --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-blog/options.json @@ -0,0 +1,14 @@ +{ + "title": { + "message": "Blog", + "description": "The title for the blog used in SEO" + }, + "description": { + "message": "Blog", + "description": "The description for the blog used in SEO" + }, + "sidebar.title": { + "message": "Publicaciones recientes", + "description": "The label for the left sidebar" + } +} diff --git a/i18n/es/docusaurus-plugin-content-docs/current.json b/i18n/es/docusaurus-plugin-content-docs/current.json new file mode 100644 index 000000000000..dc9d21a0b2af --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/current.json @@ -0,0 +1,62 @@ +{ + "version.label": { + "message": "v2 ⚡", + "description": "The label for version current" + }, + "sidebar.docs.category.Get Started": { + "message": "Primeros pasos", + "description": "The label for category 'Get Started' in sidebar 'docs'" + }, + "sidebar.docs.category.Tutorials": { + "message": "Tutoriales", + "description": "The label for category 'Tutorials' in sidebar 'docs'" + }, + "sidebar.docs.category.Design Workflows": { + "message": "Diseñar Workflows", + "description": "The label for category 'Design Workflows' in sidebar 'docs'" + }, + "sidebar.docs.category.Write Jobs": { + "message": "Escribir Jobs", + "description": "The label for category 'Write Jobs' in sidebar 'docs'" + }, + "sidebar.docs.category.Platform ⚡": { + "message": "Plataforma ⚡", + "description": "The label for category 'Platform ⚡' in sidebar 'docs'" + }, + "sidebar.docs.category.Build & Manage Workflows": { + "message": "Crear y gestionar Workflows", + "description": "The label for category 'Build & Manage Workflows' in sidebar 'docs'" + }, + "sidebar.docs.category.Monitor History": { + "message": "Monitorear el historial", + "description": "The label for category 'Monitor History' in sidebar 'docs'" + }, + "sidebar.docs.category.Manage Projects": { + "message": "Gestionar Projects", + "description": "The label for category 'Manage Projects' in sidebar 'docs'" + }, + "sidebar.docs.category.Manage Users & Credentials": { + "message": "Gestionar usuarios y Credentials", + "description": "The label for category 'Manage Users & Credentials' in sidebar 'docs'" + }, + "sidebar.docs.category.CLI": { + "message": "CLI", + "description": "The label for category 'CLI' in sidebar 'docs'" + }, + "sidebar.docs.category.Deployment": { + "message": "Despliegue", + "description": "The label for category 'Deployment' in sidebar 'docs'" + }, + "sidebar.docs.category.Migrate to v2": { + "message": "Migrar a v2", + "description": "The label for category 'Migrate to v2' in sidebar 'docs'" + }, + "sidebar.docs.category.Contribute": { + "message": "Contribuir", + "description": "The label for category 'Contribute' in sidebar 'docs'" + }, + "sidebar.docs.link.Community Forum": { + "message": "Foro de la comunidad", + "description": "The label for link 'Community Forum' in sidebar 'docs', linking to 'https://community.openfn.org'" + } +} diff --git a/i18n/es/docusaurus-plugin-content-docs/current/get-help/support.md b/i18n/es/docusaurus-plugin-content-docs/current/get-help/support.md new file mode 100644 index 000000000000..306e74ed3b4e --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/current/get-help/support.md @@ -0,0 +1,31 @@ +--- +title: Soporte para implementaciones de OpenFn +sidebar_label: Obtener ayuda +translation_source_hash: 2a73f0ecc8314aa6d23cfc20a7193d77ea125d0f +translation_review_status: machine +--- + +## ¡Pregunta a la Comunidad! {#ask-the-community} + +Si necesitas ayuda para empezar, tienes preguntas o quieres compartir +comentarios sobre el producto, primero visita nuestra +**[Comunidad](https://community.openfn.org)**. Nuestro equipo central y otras +personas que implementan OpenFn revisan todas las publicaciones para ayudarse +entre sí, compartir ejemplos y difundir novedades del producto. + +## ¿Tienes una pregunta sobre tu Project en OpenFn.org? {#have-a-question-about-your-project-on-openfnorg} + +Si usas la plataforma alojada de OpenFn (SaaS) y tienes una pregunta privada +sobre tu Project, tu cuenta o tu facturación, escribe a nuestro equipo central a +[support@openfn.org](mailto://support@openfn.org). + +## ¿Necesitas una mano? {#need-helping-hands} + +El equipo central de OpenFn y nuestros socios certificados ofrecen soporte +empresarial, servicios de implementación y desarrollo, y capacitaciones para +poner en marcha a tu equipo. Visita nuestro sitio web: + +- Sobre los [servicios y precios de OpenFn](https://www.openfn.org/pricing) +- Sobre nuestros [socios certificados](https://www.openfn.org/partners) + + diff --git a/i18n/es/docusaurus-plugin-content-docs/current/get-started/home.md b/i18n/es/docusaurus-plugin-content-docs/current/get-started/home.md new file mode 100644 index 000000000000..e6c55cf217d5 --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/current/get-started/home.md @@ -0,0 +1,154 @@ +--- +title: ¿Qué es OpenFn? +id: home +sidebar_label: ¿Qué es OpenFn? +slug: / +translation_source_hash: c4af9efb3157acd6020bb65eaa98b3d278887e0b +translation_review_status: machine +--- + +**OpenFn es el principal +[bien público digital](https://digitalpublicgoods.net/digital-public-goods/) +para la automatización de flujos de trabajo**. + +Es una plataforma que ya han usado más de 70 ONG y ministerios de gobierno para +automatizar e integrar procesos de negocio y sistemas de información críticos. + +**Conecta cualquier aplicación** con la biblioteca de [Adaptors](/adaptors/) de +código abierto de OpenFn (es decir, conectores). Desde los servicios de última +milla hasta los reportes de alcance nacional, OpenFn mejora la eficiencia y la +efectividad, y habilita una interoperabilidad segura, estable y escalable en +todos los niveles. + +OpenFn se puede desplegar localmente o en la +[plataforma segura alojada en la nube](https://openfn.org/pricing). Consulta la +[documentación de despliegue](/es/documentation/deploy/options) para conocer más +sobre las opciones y los requisitos de despliegue. + +Para apoyar a quienes implementan, OpenFn cuenta con una +[comunidad](https://community.openfn.org) en línea, documentación y +[soporte](mailto://support@openfn.org). Escribe a +[partnerships@openfn.org](mailto://partnerships@openfn.org) para conocer más +sobre los socios de implementación de OpenFn y el Programa de Socios de OpenFn. + +:::tip Automatización, integración e interoperabilidad + +OpenFn es software de código abierto que les facilita a los gobiernos y a las +ONG _conectar_ las distintas tecnologías que usan, automatizar procesos de +negocio críticos y escalar sus intervenciones. OpenFn habilita la +automatización, la integración y la interoperabilidad de datos para las +organizaciones de mayor impacto del mundo. + +::: + +## Nuestros productos {#our-products} + +OpenFn ofrece un conjunto de productos, todos ellos interoperables entre sí. +Esto les da a nuestros usuarios la libertad de cambiar entre cualquiera de los +productos de OpenFn. + +Todos los productos de OpenFn, con excepción del iPaaS de OpenFn v1, forman +parte del `OpenFn Integration Toolkit`, que es gratuito y de código abierto y es +un **bien público digital** (un "DPG", por sus siglas en inglés) reconocido en +el [Registro de DPG](https://digitalpublicgoods.net/registry/) y en la +[Global Goods Guidebook](https://digitalsquare.org/resourcesrepository/global-goods-guidebook) +de Digital Square. + +Los productos principales de OpenFn incluyen: + +- **[OpenFn/lightning](https://github.com/OpenFn/lightning)**: nuestra + plataforma de código abierto de integración de datos y automatización de + flujos de trabajo. Es la versión "v2", la que está en uso actualmente. +- OpenFn/platform: la primera versión de nuestra plataforma. Reemplazada por la + v2 y con retiro previsto para 2025 +- [**OpenFn/adaptors**](https://github.com/OpenFn/adaptors): código fuente de + los adaptors +- [**OpenFn/kit**](https://github.com/OpenFn/kit): CLI, herramientas para + desarrolladores y entornos de ejecución de JavaScript +- [**OpenFn/docs**](https://github.com/OpenFn/docs): documentación y código + fuente de docs.openfn.org + +Consulta todos los productos y el código en +[GitHub.com/OpenFn](https://github.com/OpenFn). + +### OpenFn v2: Lightning ⚡ + +Cuando escuches "OpenFn", piensa en +[OpenFn/lightning](https://github.com/OpenFn/lightning/). La v2 es una +aplicación web de automatización de flujos de trabajo _totalmente de código +abierto_ que se puede desplegar y ejecutar en cualquier lugar. Está diseñada +para gobiernos y ONG que buscan capacidades de última generación en +automatización de flujos de trabajo e integración e interoperabilidad de datos, +con gestión de usuarios y auditoría completas, ya sea en una plataforma +gestionada _o_ totalmente autoalojada. + +La versión 2 se apoya en la misma tecnología central, probada y confiable, de +OpenFn v1, y viene con una interfaz visual mejorada para construir +integraciones. + +![Canvas de Workflow de OpenFn](/img/case_referral_workflow.webp) + +**Echa un vistazo a la +[lista de reproducción OpenFn v2 Basics](https://www.youtube.com/watch?v=U0MXYRXkDnI&list=PL1pD3-abjHJ0L01RjouO2xOWKtEUYi8e4&ab_channel=OpenFn.org)** +en YouTube para ver videos que te ayudarán a empezar rápidamente, o revisa las +demás páginas de documentación del sitio. + +:::info OpenFn v2 reemplaza a la v1 + +OpenFn v2 está disponible para cualquier usuario nuevo. Todas las organizaciones +que hoy usan la plataforma heredada OpenFn v1 serán migradas a OpenFn v2 para +finales de 2024. + +::: + +### OpenFn v1 + +OpenFn v1 es la _plataforma de integración como servicio_ (o "iPaaS") heredada +de OpenFn, lanzada por primera vez en 2015. OpenFn v1 tenía un núcleo abierto +con una aplicación web propietaria. + +La plataforma v1 será retirada en 2025 y reemplazada por OpenFn v2, que es +totalmente de código abierto (ver arriba). + +### Herramientas de desarrollo de OpenFn {#openfn-developer-tooling} + +[OpenFn/kit](https://github.com/OpenFn/kit) ofrece un CLI y un conjunto de +herramientas para desarrolladores que sirven para escribir y probar workflows, +gestionar Projects de OpenFn y desarrollar +[Adaptors](https://github.com/openfn/adaptors). + +:::note Explora todo el código de OpenFn + +Puedes consultar la documentación técnica y el código fuente de las herramientas +de integración y los adaptors de OpenFn, que son totalmente de código abierto +("FOSS"), en sus respectivos repositorios en +[GitHub.com/OpenFn](https://github.com/openfn), o revisar la sección +[Despliegue](/es/documentation/deploy/options) para ver un resumen de las +opciones FOSS y documentación adicional. + +::: + +## Comunidad {#community} + +Para hacer preguntas, reportar problemas o aprender de otras personas que +implementan OpenFn, visita nuestro foro de Discourse en +[community.openfn.org](https://community.openfn.org). Regístrate y únete a la +conversación. Normalmente es la forma más rápida de obtener ayuda si tienes +preguntas que no se responden aquí. + +Si tienes preguntas sobre nuestros productos, pregunta en la Comunidad o escribe +al equipo central a [support@openfn.org](mailto:support@openfn.org). + +## ¿Quién lo desarrolla? {#who-is-it-built-by} + +El principal responsable de OpenFn es +[Open Function Group](https://openfn.org/about), un equipo global de +especialistas en automatización de flujos de trabajo e integración de datos, y +contribuyentes principales de OpenFn. Conoce más sobre la gobernanza de OpenFn +[aquí](https://github.com/OpenFn/governance). + +El [bien público digital](https://app.digitalpublicgoods.net/a/11038) OpenFn ha +sido desarrollado por y para la creciente comunidad de ONG, gobiernos, socios +"tech-for-good" y contribuyentes de código abierto que trabajan en +intervenciones de salud y humanitarias en países de ingresos bajos y medios +(LMIC). diff --git a/i18n/es/docusaurus-plugin-content-docs/current/get-started/terminology.md b/i18n/es/docusaurus-plugin-content-docs/current/get-started/terminology.md new file mode 100644 index 000000000000..7b5e39e1c0fa --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/current/get-started/terminology.md @@ -0,0 +1,318 @@ +--- +title: Conceptos clave +translation_source_hash: 88f1bae70e80318a23a5c56152c2e9da1d0d37e4 +translation_review_status: machine +--- + +A lo largo del OpenFn Integration Toolkit y de este sitio de documentación +encontrarás terminología propia de OpenFn que es importante entender. Esta +página es tu guía de referencia: un glosario de las palabras más importantes +_específicas de OpenFn_ y su significado. + +:::tip ¿Falta algo? + +Si te encontraste con una palabra, frase o concepto que crees que falta en esta +página, abre un issue en [OpenFn/docs](https://github.com/OpenFn/docs), sugiere +una edición a +[esta página](https://github.com/OpenFn/docs/blob/main/docs/get-started/terminology.md) +o pregunta en la [Comunidad](https://community.openfn.org) + +::: + +Ten en cuenta que si buscas un glosario de términos genéricos de integración de +datos (en lugar de estos términos _específicos de OpenFn_), dirígete a la página +[Glosario de integración](/es/documentation/get-started/glossary) en la sección +de Diseño. Si no, ¡sigue leyendo! + +## Project + +Un Project es una agrupación administrativa en OpenFn, algo así como un "espacio +de trabajo". + +En la plataforma (OpenFn/lightning), los Projects definen quién puede acceder a +la configuración y al historial de tus Workflows de OpenFn. Los Projects tienen +una persona propietaria y uno o más Collaborators. + +En despliegues y desarrollo local, un Project también corresponde a un archivo +[`project.yaml`](/es/documentation/deploy/portability-versions#v2), que define +la configuración de un Project. + +En cualquiera de los dos casos, un Project contiene Workflows, Triggers, +Credentials y todo lo que necesitas para automatizar e integrar con OpenFn. + +## Workflow + +:::tip + +¡Los Workflows son la parte del **"qué hacer"** de la automatización! + +::: + +Un Workflow es una secuencia estructurada de tareas, procesos o acciones que se +ejecutan automáticamente según reglas, Triggers y lógica predefinidos. + +Cuando se trabaja con IA, los Workflows aportan la ejecución estructurada que se +necesita para convertir los hallazgos de un LLM en acciones concretas, mientras +que los agentes de IA permiten una toma de decisiones más dinámica dentro de los +Workflows. + +Un Workflow es un conjunto formado por un Trigger, Steps, Paths y lógica +personalizada, conectados entre sí para automatizar un proceso de negocio o una +tarea específica. Un Workflow se configura desde el Canvas en la aplicación web, +o localmente (mediante código). + +La automatización en OpenFn gira en torno a los +[Workflows](/es/documentation/build/workflows), que pueden tener uno o varios +Steps. Los Workflows pueden ejecutarse en tiempo real (a partir de un evento, +por ejemplo el registro de un nuevo paciente), de forma programada (por ejemplo, +todos los días a las 8 a.m.) o manualmente, cuando se necesite. + +Piensa en un Workflow como un conjunto de instrucciones que le darías a una +persona del equipo (por ejemplo: crea un registro de Paciente nuevo en OpenMRS +cuando llegue de CommCare un formulario con un cliente recién registrado; +exporta los datos a DHIS2 todas las semanas, los viernes a las 11 p.m.; envía un +SMS con el número de confirmación de pago cuando se reciba el mensaje de +confirmación de pago, etc.). + +Los Workflows más comunes automatizan: + +- Reportes para un monitoreo de programas más rápido y completo (en especial, + reportes desde dispositivos móviles hacia un MIS) +- Pasos rutinarios de ETL de datos (extracción, transformación y carga) y de + limpieza de datos +- Alertas (SMS, correo electrónico) +- Referencias entre sistemas de organizaciones socias +- Asignación o aprobación de tareas +- Reporte de quejas o de casos +- Transacciones financieras o pagos + +:::note Los Workflows son reutilizables + +Los Workflows son totalmente configurables y reutilizables. También pueden +encadenarse para automatizar procesos de varios pasos y sincronizaciones de +datos bidireccionales, de modo que los datos se mantengan consistentes entre +varias aplicaciones (usando patrones Saga multiaplicación). + +::: + +### Adaptor + +:::tip + +¡Los Adaptors son la parte del **"dónde hacerlo"** de la automatización! + +::: + +Los [Adaptors](/adaptors) de OpenFn son módulos de código abierto que le dan a +tus Workflows las funcionalidades que necesitan para comunicarse con la API de +un sistema en particular. Algunos ejemplos son [dhis](/adaptors/dhis2), +[`postgresql`](/adaptors/postgresql) y [`http`](/adaptors/packages/http-docs), +entre otros. Actualmente hay más de 70 adaptors activos, y cualquiera puede +crear uno nuevo o mejorar los existentes. Consulta +[GitHub/Adaptors](https://github.com/OpenFn/adaptors) para ver el código fuente. + +### Credential + +:::tip + +¡Los Credentials son la parte del **"cómo iniciar sesión"** de la +automatización! + +::: + +Un Credential se usa para autenticarse ante una aplicación de destino (por +ejemplo, el usuario, la contraseña y la URL de acceso de una base de datos) para +que un Step de un Workflow pueda ejecutarse. Según el modelo de seguridad de +OpenFn, los Credentials se mantienen separados de los Workflows para asegurar +que los usuarios y contraseñas almacenados (todos ellos cifrados) no se filtren +ni queden al alcance de las personas equivocadas. + +## Trigger + +:::tip + +¡Los Triggers son la parte del **"cuándo hacerlo"** de la automatización! + +::: + +Un [Trigger](/es/documentation/build/triggers) determina **cómo y cuándo** deben +ejecutarse los Workflows automáticamente (por ejemplo, en tiempo real o según +una programación). Cuando se activan, los Triggers crean un nuevo +[Work Order](/es/documentation/get-started/terminology#work-order) y ejecutan (o +"corren") el Workflow. + +Puedes configurar un Trigger de tipo "Webhook Event" si quieres que tu Workflow +se ejecute en tiempo real cuando ocurra un evento en una aplicación externa (por +ejemplo, el envío de un formulario nuevo o la recepción de una notificación +nueva). + +Puedes configurar un Trigger de tipo "Cron" si quieres que tu Workflow se +ejecute según una programación específica (por ejemplo, todos los días a las 8 +a.m., o el primer lunes de cada mes). + +## Work Order + +:::tip + +Los Work Orders registran **"cuándo y qué activó"** la automatización, y nos +ayudan a monitorear si el Workflow se completó correctamente y en qué momento. + +::: + +Un Work Order es una solicitud de ejecución de un Workflow con una entrada +determinada (por ejemplo, el envío de un formulario nuevo o el registro de un +paciente que necesita procesarse). + +Se crea un Work Order cada vez que se activa el Trigger de un Workflow, o +manualmente por parte de un usuario administrador. + +Para que un Work Order se complete correctamente, el Work Order debe llegar sin +errores a un Step final: así se garantiza que el procesamiento terminó. Es +posible que se necesiten varios "Runs" del Workflow para que un Work Order +determinado se considere exitoso. + +Los Work Orders les permiten a los usuarios monitorear de cerca si cada entrada +individual (por ejemplo, el "registro de paciente 123") es procesada +correctamente por un Workflow determinado, con una experiencia de auditoría +similar a la gestión de casos. + +Imagina que hay un Workflow configurado para crear un paciente nuevo en OpenMRS +cada vez que se abre un caso nuevo en CommCare. Si durante la próxima semana se +abren 5 casos en CommCare, verás 5 Work Orders distintos para ese único +Workflow. Si 4 Work Orders son exitosos y uno falla, verás 4 pacientes nuevos en +OpenMRS, y tu administrador de sistemas habrá recibido una notificación de que +uno de esos pacientes no se pudo crear (o se aplicará el manejo de errores más +robusto que hayas configurado). + +![Work Order](/img/work_order_shot.webp) + +:::note + +Normalmente hay una correspondencia de uno a uno entre los Work Orders y las +cosas del mundo real con las que trabajas. Podría crear un Workflow que obtenga +de DHIS2 todos los datos de eventos actualizados de las últimas 2 semanas y los +publique en un mapa público usando CartoDB. Este Workflow se activará en +intervalos de tiempo definidos, cada 2 semanas en este caso, y al cabo de un mes +veremos solo 2 Work Orders en OpenFn (o sea, uno cada dos semanas). Cada Work +Order tendrá un estado de éxito o de falla, con Runs asociados que registran los +detalles de cada transacción y cuántos registros de eventos se procesaron. + +::: + +## Run + +:::tip + +¡Los Runs registran **"qué pasó"** en la automatización! + +::: + +Un Run es un intento individual de ejecución para completar un Work Order. +Pueden existir varios Runs de un Workflow para cumplir con un mismo Work Order +(porque el primer Run puede fallar y hay que reintentarlo para que se procese +correctamente). + +Los Runs tienen horas de inicio, horas de finalización, logs y códigos de estado +que indican cuándo ocurrieron, qué hicieron y si tuvieron éxito o no. + +![Canvas de Workflow de OpenFn](/img/run_view_logs.webp) + +Imagina que hay un Workflow configurado para crear un paciente nuevo en OpenMRS +cada vez que se abre un caso nuevo en CommCare. Si hoy se crea 1 paciente, +entonces: + +- Se creará 1 Work Order en OpenFn. Esto activará un Run para crear el paciente + en OpenMRS. +- Si ese Run falla por un error (por ejemplo, la contraseña del usuario de + OpenMRS es incorrecta, o al paciente le falta información obligatoria), el + "Status" de ese Run y del Work Order asociado aparecerá como `failed`. +- Los usuarios de OpenFn pueden corregir el error y luego elegir "rerun" para + volver a ejecutar ese Run fallido. Esto creará un 2.º Run relacionado con el + Work Order original. Si tiene éxito, el "Status" del 2.º Run y del Work Order + aparecerá como "success". + +### Logs + +Los logs son los registros que genera el motor de ejecución de Workflows para +capturar las actividades realizadas al ejecutar un Workflow o un Step +específico. + +Quienes desarrollan en OpenFn pueden controlar qué aparece en los logs editando +las sentencias `console.log(...)` en las expresiones de Job de los Steps +individuales. + +![Logs](/img/logs_run.webp) + +## History + +En la plataforma, la página History muestra la lista de todos los Work Orders y +Runs que se han procesado en un Project. + +![History](/img/case-referral-history.webp) + +## Inspector + +En la plataforma, la interfaz del Inspector les permite a los usuarios editar, +probar y ejecutar Workflows. + +El Inspector tiene 3 interfaces principales: `Input`, `Editor` y `Output`. + +![Inspector](/img/inspector_interfaces.webp) + +### Input + +Un Input son los datos (`json`) que se usan como Input inicial para que un Step +de un Workflow los utilice al ejecutarse. Cada Run tendrá un Input (estado +inicial) y un Output (estado final). + +Los Inputs pueden crearse automáticamente a partir de un evento de webhook (por +ejemplo, un mensaje reenviado o un payload JSON enviado a OpenFn) o de otro Step +del Workflow, o bien manualmente por parte de un usuario de OpenFn. + +Ejemplo de Input a partir del envío de un formulario desde una aplicación móvil +de recolección de datos (por ejemplo, Kobo, ODK o CommCare): + +```json +{ + "data": { + "form": { + "@name": "Register New Patient", + "case": { + "@case_id": "a9bX12c", + "@date_modified": "2021-01-21T07:08:19.431000Z", + "@user_id": "aaa", + "@xmlns": "http://commcarehq.org/case/transaction/v2", + "create": { + "case_name": "John Doe", + "age": 16, + "case_type": "patient", + "owner_id": "alan.worker" + } + } + } + } +} +``` + +### Output + +Un Output son los datos finales (`json`) que produce un Step de un Workflow, +según la lógica de negocio definida en la expresión de Job de ese Step. Los +Outputs se pasan al siguiente Step del Workflow y/o a la aplicación de destino +conectada. + +Ejemplo de Output si el envío de formulario del ejemplo anterior (ver la sección +de arriba) se mapeara a una aplicación de gestión de casos conectada: + +```json +{ + "data": { + "patient": { + "full_name": "John Doe", + "age_at_enrollment": 16, + "type": "new", + "source": "mobile-app" + } + } +} +``` diff --git a/i18n/es/docusaurus-plugin-content-docs/current/get-started/try-out.md b/i18n/es/docusaurus-plugin-content-docs/current/get-started/try-out.md new file mode 100644 index 000000000000..005c7cedd1d2 --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/current/get-started/try-out.md @@ -0,0 +1,60 @@ +--- +title: Prueba la v2⚡ +id: try-out +sidebar_label: Prueba la v2⚡ +translation_source_hash: 23289e04c3acffebfc62930b673c2f85e50f6d82 +translation_review_status: machine +--- + +Si te interesa probar OpenFn v2⚡ hoy mismo, tienes 3 opciones: + +## 1. Regístrate para obtener una cuenta gratuita {#1-register-for-a-free-account} + +Regístrate para obtener una cuenta gratuita en el servicio alojado de OpenFn.org +y crea tu propio Project privado. Para hacerlo, visita: +[www.openfn.org/register](https://www.openfn.org/register) + +Ten en cuenta que esta cuenta gratuita tiene límites. Mejora tu plan para +acceder a más funcionalidades en la plataforma segura alojada de OpenFn. Conoce +más en [nuestro sitio web](https://www.openfn.org/pricing). + +:::tip ¿Ya tienes una cuenta? + +Visita [www.openfn.org/login](https://www.openfn.org/login) para iniciar sesión +en tu cuenta de Lightning v2. Si solo tienes un usuario de la v1, tendrás que +crear una cuenta nueva de v2 en +[www.openfn.org/register](https://www.openfn.org/register). + +::: + +## 2. Inicia sesión en el sitio de demostración de OpenFn {#2-log-into-the-openfn-demo-site} + +Visita [demo.openfn.org](https://demo.openfn.org) y usa las siguientes +credenciales para iniciar sesión y explorar la plataforma: + +- usuario: `demo@openfn.org` +- contraseña: `welcome12345` + +:::warning + +El sitio de demostración se reinicia cada 24 horas, por lo que se perderá +cualquier cambio de configuración que hagas. Por eso, no uses este sitio para +configuraciones que quieras conservar. + +::: + +## 3. Instala OpenFn/lightning localmente {#3-install-openfnlightning-locally} + +Instala OpenFn v2 localmente para acceder al software de código abierto y +explorarlo sin límites. Consulta nuestro repositorio de GitHub para ver la +documentación para desarrolladores: +[github.com/OpenFn/lightning](https://github.com/OpenFn/lightning). + +:::info ¿Tienes preguntas? + +Revisa esta documentación para conocer más detalles sobre funcionalidades +específicas (ver el menú lateral), explora la +[página principal de la documentación](/es/documentation/) o publica tus +preguntas en la [Comunidad](https://community.openfn.org). + +::: diff --git a/i18n/es/docusaurus-theme-classic/footer.json b/i18n/es/docusaurus-theme-classic/footer.json new file mode 100644 index 000000000000..0279f041812f --- /dev/null +++ b/i18n/es/docusaurus-theme-classic/footer.json @@ -0,0 +1,42 @@ +{ + "link.title.This Site": { + "message": "Este sitio", + "description": "The title of the footer links column with title=This Site in the footer" + }, + "link.title.Community": { + "message": "Comunidad", + "description": "The title of the footer links column with title=Community in the footer" + }, + "link.title.More": { + "message": "Más", + "description": "The title of the footer links column with title=More in the footer" + }, + "link.item.label.Articles": { + "message": "Artículos", + "description": "The label of footer link with label=Articles linking to articles" + }, + "link.item.label.Adaptors": { + "message": "Adaptors", + "description": "The label of footer link with label=Adaptors linking to adaptors" + }, + "link.item.label.Forum": { + "message": "Foro", + "description": "The label of footer link with label=Forum linking to https://community.openfn.org" + }, + "link.item.label.Stack Overflow": { + "message": "Stack Overflow", + "description": "The label of footer link with label=Stack Overflow linking to https://stackoverflow.com/questions/tagged/openfn" + }, + "link.item.label.Twitter": { + "message": "Twitter", + "description": "The label of footer link with label=Twitter linking to https://twitter.com/openfn" + }, + "link.item.label.OpenFn.org": { + "message": "OpenFn.org", + "description": "The label of footer link with label=OpenFn.org linking to https://www.openfn.org" + }, + "link.item.label.GitHub": { + "message": "GitHub", + "description": "The label of footer link with label=GitHub linking to https://github.com/openfn" + } +} diff --git a/i18n/es/docusaurus-theme-classic/navbar.json b/i18n/es/docusaurus-theme-classic/navbar.json new file mode 100644 index 000000000000..f56684752de1 --- /dev/null +++ b/i18n/es/docusaurus-theme-classic/navbar.json @@ -0,0 +1,22 @@ +{ + "title": { + "message": "OpenFn", + "description": "The title in the navbar" + }, + "logo.alt": { + "message": "OpenFn", + "description": "The alt text of navbar logo" + }, + "item.label.Docs": { + "message": "Documentación", + "description": "Navbar item with label Docs" + }, + "item.label.Adaptors": { + "message": "Adaptors", + "description": "Navbar item with label Adaptors" + }, + "item.label.Articles": { + "message": "Artículos", + "description": "Navbar item with label Articles" + } +} diff --git a/sidebars-adaptors.js b/sidebars-adaptors.js index fe4b96418fd7..b94e3b8b5614 100644 --- a/sidebars-adaptors.js +++ b/sidebars-adaptors.js @@ -25,28 +25,38 @@ if ( return r; }, Object.create(null)); + // Every adaptor repeats the same item labels ('Functions', 'Overview', ...). + // Docusaurus derives a sidebar item's translation key from `key ?? label`, + // so without an explicit `key` those labels collide and the build throws + // `Multiple docs sidebar items produce the same translation key` for any + // non-default locale. Namespacing each key by adaptor keeps them unique. const items = adaptors.sort().map(a => { const base = { type: 'category', label: a.name, + key: a.name, items: [ { type: 'doc', label: 'Functions', + key: `${a.name}-functions`, id: a.docsId, }, { type: 'doc', label: 'Configuration', + key: `${a.name}-configuration`, id: a.configurationSchemaId, }, groupedJobs[a.name] && groupedJobs[a.name].length > 0 ? { type: 'category', label: 'Examples', + key: `${a.name}-examples`, items: groupedJobs[a.name].map(j => ({ type: 'doc', label: j.name, + key: `library/${j.id}`, id: `library/${j.id}`, })), } @@ -54,11 +64,13 @@ if ( { type: 'doc', label: 'Changelog', + key: `${a.name}-changelog`, id: a.changelogId, }, { type: 'doc', label: 'README.md', + key: `${a.name}-readme`, id: a.readmeId, }, ], @@ -70,6 +82,7 @@ if ( base.items.unshift({ type: 'doc', label: 'Overview', + key: `${a.name}-overview`, id: a.name, }); } @@ -88,7 +101,7 @@ if ( const extras = overviews .filter(id => !adaptors.map(a => `${a.name}`).includes(id)) - .map(id => ({ type: 'doc', id, label: id })); + .map(id => ({ type: 'doc', id, label: id, key: id })); list = [...items, ...extras].sort((a, b) => a.label.localeCompare(b.label)); } else { diff --git a/sidebars-main.js b/sidebars-main.js index 92ca90f868c2..d6ab10d3b7d7 100644 --- a/sidebars-main.js +++ b/sidebars-main.js @@ -161,6 +161,7 @@ module.exports = { 'contribute/writing-code', 'contribute/writing-docs', 'contribute/style-guide', + 'contribute/translating', ], }, 'get-help/support', diff --git a/src/pages/index.js b/src/pages/index.js index 4ef9e65e6de7..40905ef9f161 100644 --- a/src/pages/index.js +++ b/src/pages/index.js @@ -2,7 +2,7 @@ import React, { useCallback } from 'react'; import clsx from 'clsx'; import Layout from '@theme/Layout'; import Link from '@docusaurus/Link'; -import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import Translate, { translate } from '@docusaurus/Translate'; import useBaseUrl from '@docusaurus/useBaseUrl'; import Particles from 'react-particles'; import { loadFull } from 'tsparticles'; @@ -10,77 +10,104 @@ import styles from './styles.module.css'; const highlights = [ { - title: 'Job Writing Guide', + title: translate({ + id: 'homepage.highlights.jobWritingGuide.title', + message: 'Job Writing Guide', + }), link: 'documentation/jobs/job-writing-guide', - description: 'Writing a job for OpenFn? Start here', + description: translate({ + id: 'homepage.highlights.jobWritingGuide.description', + message: 'Writing a job for OpenFn? Start here', + }), }, { - title: 'CLI Usage Examples', + title: translate({ + id: 'homepage.highlights.cliUsage.title', + message: 'CLI Usage Examples', + }), link: 'documentation/cli-usage', - description: 'See what the CLI can do at a glance', + description: translate({ + id: 'homepage.highlights.cliUsage.description', + message: 'See what the CLI can do at a glance', + }), }, { - title: 'JavaScript Tips & Tricks', + title: translate({ + id: 'homepage.highlights.javascriptTips.title', + message: 'JavaScript Tips & Tricks', + }), link: 'documentation/cli-usage', - description: 'Level up your code', + description: translate({ + id: 'homepage.highlights.javascriptTips.description', + message: 'Level up your code', + }), }, ]; const features = [ { - title: 'Docs', + title: translate({ id: 'homepage.features.docs.title', message: 'Docs' }), link: 'documentation', imageUrl: 'img/undraw_Code_review_re_woeb.svg', description: ( - <> + Documentation on all aspects of OpenFn, the leading digital public good for workflow automation. - + ), }, { - title: 'Adaptors', + title: translate({ + id: 'homepage.features.adaptors.title', + message: 'Adaptors', + }), link: 'adaptors', imageUrl: 'img/undraw_pair_programming_njlp.svg', description: ( - <> + Searchable and browseable adaptors docs, examples, changelogs, and overviews for connecting the world's most common DPGs. - + ), }, { - title: 'Articles', + title: translate({ + id: 'homepage.features.articles.title', + message: 'Articles', + }), link: 'articles', imageUrl: 'img/undraw_Portfolio_update_re_jqnp.svg', description: ( - <> + How to prepare for data integration? How to structure external IDs? How to... - + ), }, { - title: 'Blog', + title: translate({ id: 'homepage.features.blog.title', message: 'Blog' }), link: 'https://openfn.org/blog', imageUrl: 'img/undraw_reading_time_gvg0.svg', description: ( - <> + We help the world's most promising social impact interventions achieve scale through automation, data integration, and interoperability. These are their stories. - + ), }, { - title: 'Enterprise', + title: translate({ + id: 'homepage.features.enterprise.title', + message: 'Enterprise', + }), link: 'https://www.openfn.org', imageUrl: 'img/undraw_secure_server_s9u8.svg', description: ( - <> + Check out the enterprise-grade OpenFn integration-platform-as-a-service (iPaaS), offering free-forever plans and affordable pathways to scale. - + ), }, ]; @@ -109,9 +136,6 @@ function Feature({ imageUrl, title, description, link }) { } function Home() { - const context = useDocusaurusContext(); - const { siteConfig = {} } = context; - const particlesInit = useCallback(async engine => { await loadFull(engine); }, []); @@ -235,7 +259,13 @@ function Home() { }; return ( - +
-

OpenFn Documentation

-

{siteConfig.tagline}

+

+ OpenFn Documentation +

+ {/* The English copy here mirrors `tagline` in docusaurus.config.js. + Site-level config values are not extracted for translation, so the + hero subtitle is declared as a translatable string instead. */} +

+ + The leading digital public good for workflow automation, OpenFn + makes ICT4D more efficient. + +

- Get Started + Get Started
@@ -271,13 +311,22 @@ function Home() { Newsletter -

Newsletter

+

+ + Newsletter + +

- Never miss a story from us, subscribe to our newsletter - here. + + Never miss a story from us, subscribe to our newsletter + here. +

- Subscribe + + Subscribe +
@@ -312,7 +366,11 @@ function Home() { )}
-

✨Documentation Highlights✨

+

+ + ✨Documentation Highlights✨ + +

{highlights.map(h => (