Configuración regional
El título/descripción de cada regla, y el resumen/pista de cada ocurrencia, se localizan mediante una búsqueda en un diccionario basado en claves: no están codificados de forma fija por idioma.
Cobertura actual de configuración regional
| Configuración regional | Archivo | Claves | No traducidos |
|---|---|---|---|
en (English) | src/i18n/en.json | 1355 | — (el conjunto canónico/de reserva) |
de (German) | src/i18n/de.json | 1355 | 0 |
es (Spanish) | src/i18n/es.json | 1355 | 0 |
fr (French) | src/i18n/fr.json | 1355 | 0 |
ja (Japanese) | src/i18n/ja.json | 1355 | 0 |
"No traducidos" cuenta los valores que coinciden carácter por carácter con el texto en inglés, salvo las palabras que con razón son iguales en un idioma: en francés Orientation, Interruptions y Occurrences, en alemán Frame, Frames y Element, en español Selector. Esas palabras figuran en una lista, cada una con el texto en inglés con el que se comprobó, y cuentan como traducidas. Si el inglés cambia, la entrada deja de aplicarse y la cadena cuenta como no traducida hasta que alguien la vuelva a comprobar. El recuento no puede ver una palabra en inglés que quede dentro de una frase por lo demás traducida; eso se detecta leyendo el texto, y no queda ninguna en las configuraciones regionales de arriba. Tampoco mide si una traducción es precisa o usa los términos de accesibilidad habituales de un idioma; para eso hace falta alguien que lea ese idioma.
Leer la cobertura desde el paquete
Las mismas cifras están disponibles en tiempo de ejecución, a partir de los diccionarios que incluye el paquete instalado, así que una herramienta o un sitio de documentación puede mostrarlas sin una copia del repositorio:
const { getLocaleCoverage } = require('@surea11y/core');getLocaleCoverage();// {// sourceLocale: 'en',// totalKeys: 1355,// locales: [// { locale: 'de', total: 1355, translated: 1355, missing: 0, orphaned: [], percent: 100 },// { locale: 'es', total: 1355, translated: 1355, missing: 0, orphaned: [], percent: 100 },// ...// ]// }
Para cada configuración regional, total es el número de claves en inglés con el que se mide, translated cuántos de sus valores difieren del inglés o figuran como iguales con razón, missing cuántas claves le faltan (se muestran en inglés) y orphaned las claves que tiene y el inglés no. total - translated es la columna "No traducidos" de arriba, incluidas las claves que faltan. Las claves que un perfil deja fuera de una configuración regional a propósito no se cuentan. El informe de cobertura del propio repositorio y esta función comparten una única implementación, así que siempre coinciden; el informe cuenta por separado los diccionarios de core y los de cada perfil, y esta función el diccionario combinado que usa un análisis. Es una exportación con soporte (API_STABILITY.md, puntos de extensión).
Los archivos de configuración regional son JSON simples: un mapa plano de clave a cadena traducida, en el mismo orden de claves que en.json. No contienen nada más, así que contribuir con un idioma significa editar texto y nunca tocar código.
Cada configuración regional contiene todas las claves que tiene en.json. Mantenerlo así es tarea de npm run i18n:sync: ejecútalo después de cualquier cambio en en.json y reescribe cada archivo de configuración regional no inglés para que coincida: añadiendo claves nuevas, eliminando claves que en.json ya no tiene, y dejando intactas las traducciones existentes. Una clave que añade se inicializa con el texto en inglés, lo cual cuenta como no traducido hasta que alguien lo reemplace.
Seleccionar una configuración regional
runDomRulesInPage(url, null, { locale: 'fr' }, null);
El valor predeterminado es 'en' si se omite. Se acepta cualquier cadena; una configuración regional no reconocida nunca es un error.
Cómo se elige una configuración regional
Ocurren dos cosas, en este orden. Confundirlas es la fuente habitual de confusión, así que se describen por separado.
Paso 1: elegir un diccionario (una vez por análisis)
- Usa el diccionario que coincide con tu código.
deencuentrade.json. Las mayúsculas/minúsculas no importan:pt-br,pt-BRyPT-BRencuentran todospt-BR.json. - Si no, elimina todo lo que sigue al primer
-y prueba con eso.de-DEencuentrade.json;de-ATtambién. - Si no, usa inglés.
Así que solo necesitas un de-DE.json si el alemán de Austria y de Alemania realmente debe leerse de forma distinta. Publica de.json y toda variante de alemán queda cubierta.
Paso 2: resolver cada cadena (por cadena)
Dentro del diccionario elegido, cada cadena se busca de forma individual:
- Toma el valor de la clave del diccionario elegido.
- Si esa clave falta, toma la inglesa.
- Si el inglés tampoco la tiene (algo que no debería ocurrir con una clave incorporada, pero puede pasar con una escrita a mano), usa el texto literal que la propia regla lleva.
El resultado nunca es un vacío, un undefined, ni un error lanzado. Una traducción a medias se muestra en tu idioma donde existe y en inglés en todo lo demás.
Saber qué configuración regional obtuviste realmente
El respaldo elegante tiene un inconveniente: pide un idioma que la compilación no incluye y obtienes inglés fluido de vuelta, sin nada en las cadenas que lo indique. Por eso cada resultado informa la resolución una vez, al principio:
"engine": {"tag": "a11ycore","schemaVersion": "1.0.0","locale": { "requested": "ko", "resolved": "en", "reason": "unknown-locale" }}
requested es lo que pediste (después de recortar espacios; en si no pasaste nada o pasaste algo que no es una cadena), resolved es el diccionario que se usó, y reason es uno de los siguientes:
| reason | Significado |
|---|---|
ok | Obtuviste exactamente lo que pediste, y ese diccionario contiene todas las claves. |
primary-subtag | Tu código incluía una subetiqueta sin diccionario propio, así que se usó su idioma base: pediste de-DE y obtuviste de. Es normal y esperado; no hay nada que corregir. Una diferencia solo de mayúsculas/minúsculas no es esto: DE informa ok. |
dictionary-not-loaded | El proyecto incluye ese idioma, pero esta copia del motor no lo trae incorporado y no se proporcionó ninguno. En la práctica: el paquete independiente para navegador sin su archivo lateral de configuración regional. |
unknown-locale | El proyecto no tiene esa traducción en absoluto, así que se usó inglés. ko y pt-BR caen ambos aquí actualmente. |
partial-dictionary | Se usó el diccionario, pero le faltan algunas claves, así que esas cadenas concretas recurrieron al inglés. |
Trata la lista como abierta: una versión posterior puede añadir un valor, así que compara solo con los que te interesan y deja que el resto caiga en un valor por defecto.
Si necesitas un idioma concreto, requested !== resolved es la condición que hay que comprobar en CI. Ten en cuenta que también es cierta para el caso inofensivo de primary-subtag, así que condiciónalo a reason === 'unknown-locale' || reason === 'dictionary-not-loaded' si una coincidencia de idioma base te resulta suficiente. Consulta el esquema de salida para conocer el lugar de este campo en el resultado, y API_STABILITY.md para saber qué se garantiza sobre él.
Dónde viven los diccionarios
Qué idiomas están disponibles depende de cómo cargues el motor.
| Cómo lo cargas | Qué obtienes |
|---|---|
require('@surea11y/core') | Toda la configuración regional, incorporada. Nada que configurar. |
Una integración (binding) (Playwright, Cypress, …) | Toda la configuración regional, incorporada. Nada que configurar. |
surea11y.browser.js | Inglés. Carga surea11y.i18n.<locale>.js después de él para cualquier otro idioma. |
El paquete está dividido porque viaja por la red a cada página que lo usa, y ninguna página necesita todos los idiomas. Mantener el inglés incorporado y el resto como opcional deja los demás idiomas fuera de la descarga, y evita que siga creciendo a medida que se añaden idiomas. Cada archivo lateral, surea11y.i18n.<locale>.js, ocupa más o menos lo mismo que el texto en inglés al que sustituye (entre 200 y 250 KB hoy), y una página carga solo los que usa. Nada más cambia: el paquete de Node y las integraciones no se ven afectados.
<script src="surea11y.browser.js"></script><script src="surea11y.i18n.ja.js"></script><script>const result = a11ycore.runa11yCoreInPage(location.href, null, { locale: 'ja' }, null);</script>
Pide un idioma cuyo archivo no cargaste y obtienes inglés, con engine.locale.reason establecido en dictionary-not-loaded, distinto de unknown-locale, que significa que el proyecto no tiene esa traducción en absoluto.
En Node, el mismo archivo lateral es un módulo: require('@surea11y/core/i18n/de') devuelve { locale, messages } (locale es 'de', y messages el mapa plano de clave a texto), sin necesidad del paquete para navegador.
Los mensajes de un pack están en sus propios diccionarios, que el pack enumera por configuración regional; en una configuración regional para la que el pack no tiene diccionario, sus mensajes aparecen en inglés.
Los diccionarios de revisión
Los pasos que explican a una persona cómo resolver un hallazgo sin decidir (howToCheck, consulta el esquema de salida) están en diccionarios propios, en las mismas cinco configuraciones regionales. Se mantienen fuera de los diccionarios del motor para que los pasos nunca entren en el bundle ni en una página: se añaden después del análisis, en Node, o mediante código que los importa. Core 1.14.0 y posteriores.
| Quién los lee | Cómo |
|---|---|
runDomRulesInPage, addHowToCheck, howToCheckFor, renderHtmlReport | Desde el paquete instalado, buscados por la configuración regional en minúsculas (fr-ca, después fr), y el inglés en último lugar. |
| Código que se ejecuta en un navegador (un spec de Cypress) | applyHowToCheck(result, { en, fr }) de @surea11y/core/how-to-check, con los diccionarios que importa como @surea11y/core/review/<locale>. |
a11ycore.openReport(result) en el bundle del navegador | Se obtienen de junto al bundle, o se pasan como { reviewDictionaries }. |
Un paso que falta en una configuración regional aparece en inglés, como un mensaje. Los pasos propios de una regla de pack están en inglés salvo que los traduzcan los diccionarios de su pack (core 1.15.0 y posteriores). getLocaleCoverage() no cuenta estos diccionarios. Los pasos no llevan claves, así que para mostrarlos en otra configuración regional, añádelos de nuevo:
const { addHowToCheck } = require('@surea11y/core');const inFrench = addHowToCheck(result, { locale: 'fr' });
Los diccionarios de procedimientos
Desde core 1.15.0 los pasos de revisión se escriben con los procedimientos de prueba de core, cómo evalúa una persona a mano cada criterio, y los diccionarios de revisión se generan a partir de ellos. Los diccionarios de procedimientos, @surea11y/core/procedures/<locale>, contienen los procedimientos generales, los nombres de las herramientas, las palabras de una página generada con ellos, y los nombres de los principios, pautas y criterios de WCAG y de cada faceta, en la traducción publicada de WCAG de cada idioma. Las cinco configuraciones regionales tienen todos los textos, así que una página de procedimientos está en un solo idioma de principio a fin; procedureLanguages() lo indica para cada configuración regional, y para el estándar de un pack, que puede leerse en menos.
Proporcionar tu propio diccionario
engineOptions.messages acepta { [locale]: { key: value } } y tiene prioridad sobre cualquier cosa incorporada o cargada desde un archivo lateral. Útil para sobrescribir un puñado de cadenas o para un idioma que mantienes de forma privada:
runDomRulesInPage(url, null, {locale: 'de',messages: { de: { img_altPresent_title: 'Eigener Text' } }}, null);
Las claves que no proporciones recurren al valor por defecto normalmente, así que una sobrescritura parcial es válida.
Coincidencia específica por idioma
Cinco reglas juzgan el texto por frases conocidas, así que llevan listas de palabras además de mensajes: link-name-quality ("click here", 「こちら」), heading-quality ("Untitled", 「見出し」), form-control-label-quality ("Label", 「入力欄」), page-title-patterns ("Home", 「トップページ」) y media-alternative-transcript-evidence ("transcript", 「文字起こし」). Cada lista cubre en, de, es, fr y ja. La regla skip-link reconoce la redacción de los enlaces de salto en esos mismos cinco idiomas.
El inglés se comprueba siempre. La lista del idioma propio del elemento, tomado del atributo lang más cercano (el del elemento <html> para el título de la página), se añade encima. link-name-quality comprueba las listas de todos los idiomas cuando no hay ningún lang declarado en el árbol por encima del enlace, ya que el enlace puede estar en cualquiera de ellos. Comprobar todas las listas en todas partes marcaría palabras que son genéricas en un idioma y un nombre real en otro, como "Suite" o "Plus" en una página en inglés. Las palabras de transcripción son la excepción: son distintivas en todos los idiomas y una página puede enlazar una transcripción en otro idioma, así que se comprueban todas siempre. El texto se normaliza primero en NFKC, así que coinciden las formas de ancho completo como 「見出し2」.
page-title-patterns también cuenta cada carácter chino, japonés o coreano como dos al decidir si un título es demasiado corto, ya que 「お問い合わせ」 es un título completo de seis caracteres.
Dónde se usan las claves
Varios espacios de nombres de claves, todos resueltos de la misma manera:
- A nivel de regla:
meta.i18n.titleKey/meta.i18n.descriptionKey, resuelven eltitle/descriptionde una regla en cada entrada dechecksResults[]. - Informe HTML: las claves
report_*etiquetan la página que genera@surea11y/core/report: encabezados, columnas de tabla, nombres de resultados y gravedades, el titular, el paginador. El informe las lee en el idioma al que se resolvió el análisis, así que un diccionario también traduce el informe. - A nivel de compuesto: el
title/descriptionde cada resultado agregado derulesResults[], con el nombre publicado del criterio de conformidad en cada idioma. - A nivel de ocurrencia:
i18n.summaryKey/i18n.hintKey, coni18n.paramspara la interpolación de{{placeholder}}, resuelven elsummary/hintde una ocurrencia.i18n.whyKey/i18n.cautionKeyresuelven del mismo modo elwhyy elcautionde una tendencia. Consulta el esquema de salida. - Revisión:
<prefix>_review_<CODE>_step<n>,_passy_fail, en los diccionarios de revisión: elhowToCheckde una ocurrencia sin decidir. - Procedimientos:
wcag_<criterion>_<facet>_step<n>,_passy_fail,tool_<id>yrender_*, en los diccionarios de procedimientos.
Las claves de regla, de compuesto y de ocurrencia se incluyen en el resultado junto con el texto ya resuelto, así que puedes volver a renderizar en una configuración regional distinta a partir de un resultado guardado sin volver a analizar.