# 语言

> 用 ?locale= 获取协会文案的其他语言版本，从 locale 和 locales 判断实际返回了什么，告诉 Vimine 用哪种语言给某人写信。绝不使用机器翻译。

URL: https://developers.vimine.network/zh-hans/guides/languages/

协会用意大利语撰写自己的文案；如果愿意，**还可以用另一种语言**撰写，只要是 Vimine 支持的语言——目前为 `it`、`en`、`zh-Hans`、`zh-Hant`、`fr`、`es`、`de` 和 `pt-BR`。并非所有内容都有译文，也没有任何内容由机器翻译：协会没有撰写译文的地方，API 会返回其意大利语文本，并且**明确告诉您**。

本指南说明对集成而言有哪些变化：如何请求某种语言，如何解读响应，如何告诉 Vimine 用哪种语言给某人写信。

## 请求某种语言

每个返回协会文案的读取接口都接受 `?locale=`：

| 读取接口 | |
|---|---|
| `GET /v1/aps/{slug}` | 会员卡类型、付款说明、隐私声明 |
| `GET /v1/aps/{slug}/events`、`GET /v1/aps/{slug}/events/{event}` | 公开活动 |
| `GET /v1/events`、`GET /v1/events/{slug}` | 使用令牌读取的活动，包括仅限会员的活动 |

```js
const event = await vimine.public.events.get('circolo-aurora', 'festa-di-primavera', { locale: 'en' });
event.title;   // "Spring party" — 如果协会撰写了英文标题
event.locale;  // "en"：标题是英文。"it"：没有译文，您拿到的是意大利语文本
event.locales; // ["it", "en"]：该活动有标题的语言
```

不带 `?locale=` 时，语言依次由以下因素决定：会员选择的语言（使用会员令牌时）、`Accept-Language` 请求头、协会的语言。Vimine 不支持的值（`?locale=ja`）会被**忽略**，这不是错误：您会得到意大利语，并带有 `locale: "it"`。

也接受带地区的语言标签（`en-GB`）：它会被归并为对应的语言。

## 解读响应

- **`locale`** 是主要文本（例如活动标题）实际返回的语言。如果它不是您请求的语言，说明协会没有撰写译文。
- **`locales`** 是该文本已有的语言：请用它只在有意义的地方显示语言切换器。
- 替换是**逐字段**进行的：一个活动可能标题是英文、描述是意大利语。我们绝不在同一段文本中混用两种语言，也绝不编造译文。

在 `GET /v1/aps/{slug}` 上，`locale` 是响应的语言，`locales` 是协会提供的语言。

协会名称、标识（`slug`、`cod`）和法律文件永远不会被翻译：章程是一份法律文书，以意大利语为准。

公开读取接口的响应带有 `Content-Language`；当由 `Accept-Language` 决定语言时，还带有 `Vary: Accept-Language`：如果您在 API 前面放置了缓存，请遵守它——或者始终传入 `?locale=`。

## 隐私声明每种语言各有一个版本

协会的隐私声明每种语言各有一份，而且**每种语言都有自己的版本号**。如果您用 `?locale=en` 读取资料，而协会发布了英文隐私声明，那么 `privacy_notice` 就是这一份——带有 `locale: "en"`。为当事人办理入会时，请把您展示给他的内容原样传回，包括语言：

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

我们记录的证明指向的是**这一份**文件：当事人真正阅读过的那一份。

## 告诉 Vimine 用哪种语言给某人写信

`POST /v1/signup`、`POST /v1/enroll` 和活动报名都接受 `locale`：当事人在您网站上填写的页面的语言。

- 它决定**后续邮件**的语言（邮箱地址确认、欢迎邮件、报名确认）。
- 它会成为**新**账户的语言偏好。已存在的账户保留其原有偏好。
- 对于**嘉宾**——没有账户而报名活动的人——这是我们掌握的唯一信息：他收到的每封邮件都使用该语言。

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

在邮件中，协会自己的文案（活动标题、付款说明）遵循与读取接口相同的规则：协会撰写了该语言版本的就用该语言，否则用意大利语。

## 会员的语言

`GET /v1/me` 返回 `locale`：当事人选择的语言；如果从未选择过，则为 `null`。拥有 `profile:write` scope 时，您可以更改它：

```js
await vimine.me.update({ locale: 'en' }); // null 清除所选语言
```

在这里——且仅在这里——Vimine 不支持的语言才是错误：返回 `422`，`locale` 字段上带有 `code: "unsupported"`。只有在当事人自己选择了语言时才写入：不要根据浏览器推断。

## 使用 Vimine 登录

授权请求中的 `ui_locales` 是按顺序排列的偏好列表（`ui_locales=ja en`）：以 Vimine 支持的第一种语言为准。如果您没有指定，授权同意页面会依次采用浏览器的语言、协会的语言。
