# Idiomas

> Pide los textos de una asociación en otro idioma con ?locale=, distingue con locale y locales lo que se ha servido, indica en qué idioma escribir a una persona. Nunca una traducción automática.

URL: https://developers.vimine.network/es/guides/languages/

Una asociación escribe sus textos en italiano y, si quiere, **también en otro idioma**, entre los que habla Vimine
— hoy `it`, `en`, `zh-Hans`, `zh-Hant`, `fr`, `es`, `de` y `pt-BR`. No todo se traduce, y nada lo traduce una máquina: donde la asociación no ha escrito una
traducción, la API sirve su texto italiano y **te lo dice**.

Esta guía recoge lo que cambia para una integración: cómo pedir un idioma, cómo leer la respuesta, cómo indicar a
Vimine en qué idioma escribir a una persona.

## Pedir un idioma

Cada lectura que devuelve textos de una asociación acepta `?locale=`:

| Lectura | |
|---|---|
| `GET /v1/aps/{slug}` | tipos de carné, instrucciones de pago, política de privacidad |
| `GET /v1/aps/{slug}/events`, `GET /v1/aps/{slug}/events/{event}` | eventos públicos |
| `GET /v1/events`, `GET /v1/events/{slug}` | eventos con un token, incluidos los que son solo para socios |

```js
const event = await vimine.public.events.get('circolo-aurora', 'festa-di-primavera', { locale: 'en' });
event.title;   // "Spring party" — si la asociación lo ha escrito
event.locale;  // "en": el título está en inglés. "it": no hay traducción, tienes el texto italiano
event.locales; // ["it", "en"]: los idiomas en los que este evento tiene título
```

Sin `?locale=`, el idioma lo decide, por este orden: el idioma que eligió el socio (con un token de socio), la
cabecera `Accept-Language`, el idioma de la asociación. Un valor que Vimine no habla (`?locale=ja`) se **ignora**, no
es un error: recibes el italiano, con `locale: "it"`.

También se acepta una etiqueta regional (`en-GB`): se reduce a su idioma.

## Leer la respuesta

- **`locale`** es el idioma en el que ha llegado el texto principal — el título de un evento. Cuando no es el que
  pediste, la asociación no ha escrito una traducción.
- **`locales`** son los idiomas en los que existe ese texto: úsalos para mostrar un selector solo donde sea útil.
- La sustitución se hace **campo por campo**: un evento puede tener un título en inglés y una descripción en
  italiano. Nunca mezclamos dos idiomas dentro del mismo texto, y nunca nos inventamos traducciones.

En `GET /v1/aps/{slug}`, `locale` es el idioma de la respuesta y `locales` los idiomas que ofrece la asociación.

El nombre de la asociación, los identificadores (`slug`, `cod`) y los documentos legales nunca se traducen: el
estatuto es un acto jurídico, y está en italiano.

Las lecturas públicas responden con `Content-Language` y, cuando ha decidido `Accept-Language`, con
`Vary: Accept-Language`: si pones una caché delante de la API, respétalo — o pasa siempre `?locale=`.

## La política de privacidad tiene una versión por idioma

La política de privacidad de la asociación existe una vez por idioma, y **cada idioma tiene su propia versión**. Si
lees el perfil con `?locale=en` y la asociación ha publicado una política en inglés, `privacy_notice` es esa — con
`locale: "en"`. Cuando inscribas a la persona, devuelve lo que le mostraste, idioma incluido:

```js
const profile = await vimine.public.association('circolo-aurora', { locale: 'en' });

await vimineServer.enroll({
    // …
    locale: 'en',
    privacy_notice: {
        version: profile.privacy_notice.version,
        sha256: profile.privacy_notice.sha256,
        locale: profile.privacy_notice.locale
    }
});
```

La prueba que registramos nombra **ese** documento: el que la persona ha leído de verdad.

## Indicar en qué idioma escribir a una persona

`POST /v1/signup`, `POST /v1/enroll` y las inscripciones a eventos aceptan `locale`: el idioma de la página que la
persona ha rellenado en tu sitio.

- Decide el idioma de los **correos que siguen** (confirmación de la dirección, bienvenida, confirmación de la
  inscripción).
- Se convierte en la preferencia de una cuenta **nueva**. Una cuenta que ya existe conserva la suya.
- Para un **invitado** — alguien que se inscribe en un evento sin cuenta — es todo lo que sabemos: todos los correos
  que reciba estarán en ese idioma.

```js
await vimineServer.registrations.guest('festa-di-primavera', {
    email: 'marie.dupont@example.org',
    first_name: 'Marie',
    last_name: 'Dupont',
    registration_type: type.uid,
    locale: 'en'
});
```

En los correos, los textos propios de la asociación (el título del evento, las instrucciones de pago) siguen la misma
regla que las lecturas: en inglés donde la asociación los ha escrito, en italiano en los demás casos.

## El idioma del socio

`GET /v1/me` devuelve `locale`: el idioma que eligió la persona, o `null` si nunca eligió ninguno. Con el scope
`profile:write` puedes cambiarlo:

```js
await vimine.me.update({ locale: 'en' }); // null borra la elección
```

Aquí — y solo aquí — un idioma que Vimine no habla es un error: `422` con `code: "unsupported"` en el campo
`locale`. Escríbelo solo cuando la persona lo haya elegido: no lo deduzcas del navegador.

## Iniciar sesión con Vimine

`ui_locales` en la solicitud de autorización es una lista de preferencias, en orden (`ui_locales=ja en`): gana el
primer idioma que habla Vimine. Si no indicas ninguno, la página de consentimiento sigue el idioma del navegador y,
después, el de la asociación.
