Guías
Keys y catálogos
Un catálogo es un fichero JSON por idioma, y una key es el nombre al que responde un mensaje. Lo normal es que no escribas ninguna: escribes texto y el compilador la nombra por ti. Esta página trata de las veces en que quieres que la key sea tuya, que es lo que le pasa a casi todo proyecto que ya tiene una.
Cinco formas, un solo catálogo
Se mezclan sin problema en el mismo proyecto y acaban en el mismo fichero. Se elige por mensaje, no por app.
| Escribes | La key es | Úsala cuando |
|---|---|---|
t`Hola {name}` | Un hash del texto | Siempre, salvo que tengas un motivo. No nombras nada y nada se desincroniza |
t.id('inbox.title')`…` | El id que le pusiste | Quieres poder leer el catálogo, o un traductor te lo pidió |
t('inbox.title') | La clave que escribiste | El texto vive en el catálogo, y donde lo usas solo escribes su clave |
defineKeys({ … }) | El id que declaraste | La key sale de un dato, o se comparte con algo de fuera de esta app, y su texto vive solo en el catálogo |
data-verbaly="inbox.title" | El valor del atributo | El texto está en HTML que no compilas, así que nada lo extrae |
Lo normal: ninguna key
Escribe la frase. El compilador convierte el texto en un id corto y estable, lo escribe en tu catálogo fuente y genera los tipos. Si cambias la redacción sale una key nueva, y eso es lo que se busca: la traducción de la frase vieja nunca se cuela en silencio como si fuera la de la nueva.
Ids legibles
Cuando quieras abrir el catálogo y reconocer las cosas, nombra el mensaje donde lo escribes con t.id. El texto se queda en tu código y lo que aterriza en el fichero es el id:
Los puntos son una convención de nombres, y tu catálogo puede escribirlos de las dos maneras: una key plana "inbox.title", o un title dentro de un grupo inbox. Todos los comandos leen las dos y devuelven la forma que tu fichero ya tenía, así que nada te reformatea el catálogo. Los ids dinámicos (t.id(unaVar)) se dejan intactos, y un id escrito con dos textos se reporta con cada sitio que no coincide, porque todos muestran el que se escribió primero, por ruta de archivo, sin importar en qué orden cargan tus archivos.
Texto que vive en el catálogo
También puedes dejar el texto en el catálogo y escribir solo la clave en tu código. Una clave escrita como literal cuenta como usada, así que extract --prune la conserva y check comprueba que existe. Elígelo cuando el texto cambia más que el código, o cuando alguien edita los textos sin abrir un componente.
Cuando la clave sale de un dato, un mapa por slug o por id, declárala con defineKeys, más abajo, para que el compilador la vea y tu editor la compruebe.
Cada clave está tipada
Cada t de tu proyecto comprueba sus claves contra tu catálogo: el de virtual:verbaly, useT() en React, Vue y Svelte, getT() en Next.js, y el t de cualquier instancia. Una clave que escribes y que ningún catálogo tiene no compila, el error la nombra, y un mensaje con un {name} lo pide.
Una clave que viene de datos, un string o una plantilla con una parte que viene de datos como t(`status.${s}`), pasa tal cual, porque ningún catálogo puede saber qué clave será. Una variable tipada como una unión de claves, VerbalyKey incluida, también es un dato: cada clave que puede ser tiene que existir, y sus params quedan abiertos. Declara esas claves con defineKeys, más abajo, cuando quieras que check compruebe que existen y que extract --prune las conserve.
Keys que ya son tuyas
A veces la key es lo importante: la compartes con una app móvil o con una memoria de traducción, sobrevive a cualquier componente y su texto vive solo en el catálogo. Declara esas con defineKeys y Verbaly las trata como usadas, así extract --prune las conserva y check verifica que cada una existe:
import { defineKeys } from 'virtual:verbaly';
export const BannerText = defineKeys({
title: 'alerts_banner_title',
button: 'alerts_banner_button',
});Los tipos salen de tu propio catálogo, así que una key que no existe es un error ahí mismo, en la línea que la declara, y tu editor completa las que sí. Léelas donde quieras con t(BannerText.title). Los grupos se anidan lo que haga falta, y un valor vacío se salta porque vacío significa sin traducir.
De quién es un texto
Un mensaje guarda su texto en un solo sitio, y ese sitio es donde lo cambias. Un texto escrito en tu código, con t`…` o t.id, es del código: extract, los servidores de desarrollo y el build lo usan, así que una edición suya en el catálogo fuente se reemplaza, y Verbaly te dice qué archivo tiene el texto. Un texto que vive solo en el catálogo se edita ahí. Todos los comandos que leen un texto fuente leen el que se publica: check, status, review, translate, export, import, Studio y los agentes.
Una traducción recuerda para qué texto se escribió. En las claves legibles, Verbaly guarda una huella corta del texto fuente y de cada traducción en verbaly.lock, junto a tu config, tomada en el momento en que se escribe la traducción, la escriba quien la escriba. Cambia un texto fuente y sus traducciones aparecen como desactualizadas en status, check y doctor hasta que alguien las actualice, o las mantenga con verbaly review --approve. Editar una traducción la limpia sola. Las claves con hash nunca lo necesitan: un texto nuevo es una clave nueva.
Keys en HTML plano
El texto que vive en HTML que nadie compila no tiene llamada que extraer, así que la key viaja en el elemento. Escribes primero el catálogo y apuntas a él. Este sitio está hecho así, y HTML plano cubre el intérprete entero.
Dos formas de catálogo
La plana es la que escribe extract. La anidada es la que escribe una persona. Las dos se leen en todas partes, y cada comando devuelve la forma que el fichero ya tenía, así que un proyecto nunca acaba mitad y mitad.
Qué idiomas tienes
Si no listas locales, cada fichero JSON de tu carpeta de catálogos es un idioma, salvo el del pseudo-idioma: deja ahí un pt.json y se detecta. Si listas locales, esa lista es la lista entera, así que un fichero que dejó una ejecución anterior se ignora. npx verbaly doctor te dice cuál de las dos está pasando.