Skip to content

Languages

View as Markdown

An association writes its copy in Italian and, if it wants to, in another language too, among those Vimine speaks — it, en, zh-Hans, zh-Hant, fr, es, de and pt-BR today. Not everything gets translated, and nothing is translated by a machine: where the association wrote no translation, the API serves its Italian text and tells you so.

This guide is what changes for an integration: how to ask for a language, how to read the answer, how to tell Vimine which language to write to a person in.

Every read that returns an association’s copy takes ?locale=:

Read
GET /v1/aps/{slug} membership types, payment instructions, privacy notice
GET /v1/aps/{slug}/events, GET /v1/aps/{slug}/events/{event} public events
GET /v1/events, GET /v1/events/{slug} events with a token, members-only ones included
const event = await vimine.public.events.get('circolo-aurora', 'festa-di-primavera', { locale: 'en' });
event.title; // "Spring party" — if the association wrote it
event.locale; // "en": the title is in English. "it": there is no translation, you have the Italian text
event.locales; // ["it", "en"]: the languages in which this event has a title

Without ?locale= the language is decided, in order, by: the language the member chose (with a member token), the Accept-Language header, the association’s language. A value Vimine does not speak (?locale=ja) is ignored, it is not an error: you get Italian, with locale: "it".

A regional tag (en-GB) is accepted too: it is reduced to its language.

  • locale is the language the main text — an event’s title — came in. When it is not the one you asked for, the association wrote no translation.
  • locales are the languages in which that text exists: use them to show a switcher only where it is useful.
  • The replacement happens field by field: an event may have an English title and an Italian description. We never mix two languages inside the same text, and we never make translations up.

On GET /v1/aps/{slug}, locale is the language of the answer and locales the languages the association offers.

The association’s name, the identifiers (slug, cod) and legal documents are never translated: the statuto is a legal act, and it is in Italian.

Public reads answer with Content-Language and, when Accept-Language decided, with Vary: Accept-Language: if you put a cache in front of the API, honour it — or always pass ?locale=.

The privacy notice has one version per language

Section titled “The privacy notice has one version per language”

The association’s privacy notice exists once per language, and each language has its own version. If you read the profile with ?locale=en and the association published an English notice, privacy_notice is that one — with locale: "en". When you enrol the person, send back what you showed them, language included:

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
}
});

The proof we record names that document: the one the person actually read.

Saying which language to write to a person in

Section titled “Saying which language to write to a person in”

POST /v1/signup, POST /v1/enroll and event registrations take locale: the language of the page the person filled in on your site.

  • It decides the language of the mails that follow (address confirmation, welcome, registration confirmation).
  • It becomes the preference of a new account. An account that already exists keeps its own.
  • For a guest — someone who registers for an event without an account — it is all we know: every mail they receive is in that language.
await vimineServer.registrations.guest('festa-di-primavera', {
email: 'marie.dupont@example.org',
first_name: 'Marie',
last_name: 'Dupont',
registration_type: type.uid,
locale: 'en'
});

In mails, the association’s own copy (the event’s title, the payment instructions) follows the same rule as the reads: in English where the association wrote it, in Italian otherwise.

GET /v1/me returns locale: the language the person chose, or null if they never chose one. With the profile:write scope you can change it:

await vimine.me.update({ locale: 'en' }); // null clears the choice

Here — and only here — a language Vimine does not speak is an error: 422 with code: "unsupported" on the locale field. Write it only when the person chose it: do not infer it from the browser.

ui_locales on the authorization request is a preference list, in order (ui_locales=ja en): the first language Vimine speaks wins. If you name none, the consent page follows the browser’s language, then the association’s.