Плагин i18n
Плагин i18n для GramIO.
Этот плагин помогает добавить многоязычность в ваши боты с помощью синтаксиса Fluent.
Вы можете настроить типо-безопасность для него.
Плагин i18n для GramIO.
Этот плагин предоставляет удобный способ добавить многоязычность в ваши боты! Его можно использовать без GramIO, но он всегда будет учитывать его особенности.
IMPORTANT
Начиная с версии 1.0.0, у нас есть два способа написания локализации: I18n-in-TS и Fluent
Установка
npm install @gramio/i18nbun add @gramio/i18nyarn add @gramio/i18npnpm add @gramio/i18nnpm install @gramio/i18n @fluent/bundlebun add @gramio/i18n @fluent/bundleyarn add @gramio/i18n @fluent/bundlepnpm add @gramio/i18n @fluent/bundleСинтаксис I18n-in-TS
Этот синтаксис позволяет вам писать локализацию, не выходя из файлов .ts, и не требует генерации кода для типо-безопасности, а также обеспечивает удобную интеграцию с Format API из коробки!
import { format, Bot } from "gramio";
import {
defineI18n,
type LanguageMap,
type ShouldFollowLanguage,
} from "@gramio/i18n";
const en = {
greeting: (name: string) => format`Hello, ${name}!`,
and: {
some: {
nested: "Hi!!!",
},
},
} satisfies LanguageMap;
const ru = {
greeting: (name: string) => format`Привет, ${name}!`,
and: {
some: {
nested: "Hi!!!",
},
},
} satisfies ShouldFollowLanguage<typeof en>;
// Strict покажет ошибку при отсутствии ключей
// satisfies ShouldFollowLanguageStrict<typeof en>;
const i18n = defineI18n({
primaryLanguage: "en",
languages: {
en,
ru,
},
});
i18n.t("en", "greeting", "World"); // Hello, World!
i18n.t("en", "and.some.nested"); // Hi!!!
const bot = new Bot(process.env.BOT_TOKEN as string)
.derive("message", (context) => {
// вы можете взять язык из базы данных или любого другого источника и привязать его к контексту, не теряя типо-безопасности
return {
t: i18n.buildT(context.from?.languageCode),
};
})
.on("message", (context) => {
return context.send(
context.t("greeting", context.from?.firstName ?? "World")
);
});Множественные числа
import { pluralizeEnglish, pluralizeRussian } from "@gramio/i18n";
const count = 5;
console.log(`You have ${count} ${pluralizeEnglish(count, "apple", "apples")}.`); // You have 5 apples.
console.log(
`У вас ${count} ${pluralizeRussian(count, "яблоко", "яблока", "яблок")}.`
); // У вас 5 яблок.ExtractLanguages помогает извлечь типы языков из экземпляра i18n.
type EnLocalization = ExtractLanguages<typeof i18n>["en"];
type EnLocalizationKeys = keyof ExtractLanguages<typeof i18n>["en"];
type EnGreetingArgs = ExtractArgsParams<EnLocalization["greeting"]>;Синтаксис Fluent
Этот плагин помогает добавить многоязычность в ваши боты с помощью синтаксиса Fluent.
Вы можете настроить типо-безопасность для него.
Использование
Создайте папку locales с файлом ru.ftl
# Простые вещи просты.
hello-user = Привет, {$userName}!
# Сложные вещи возможны.
shared-photos =
{$userName} {$photoCount ->
[one] добавил новую фотографию
[few] добавил {$photoCount} новые фотографии
*[other] добавил {$photoCount} новых фотографий
} в {$userGender ->
[male] свою ленту
[female] свою ленту
*[other] свою ленту
}.Использование плагина
// @moduleResolution: NodeNext
// @module: NodeNext
// src/index.ts
import { Bot } from "gramio";
import { i18n } from "@gramio/i18n/fluent";
const bot = new Bot(process.env.BOT_TOKEN as string)
.extend(i18n())
.command("start", async (context) => {
return context.send(
context.t("shared-photos", {
userName: "Анна",
userGender: "female",
photoCount: 3,
})
);
})
.onError(console.error)
.onStart(console.log);
bot.start();Опции
| Ключ | Тип | По умолчанию | Описание |
|---|---|---|---|
| defaultLocale? | string | "en" | Язык по умолчанию |
| directory? | string | "locales" | Путь к папке с файлами *.ftl |
Или предоставьте клиент
import { Bot } from "gramio";
import { getFluentClient, i18n } from "@gramio/i18n/fluent";
// или getFluentClient<TypedFluentBundle>()
const client = getFluentClient({
defaultLocale: "ru",
directory: "locales",
});
const bot = new Bot(process.env.BOT_TOKEN as string)
.extend(i18n(client))
.command("start", async (context) => {
return context.send(context.t("hello-user", { userName: "Анна" }));
});IMPORTANT
См. Типо-безопасность. Для обеспечения типо-безопасности нужно указать дженерик для getFluentClient.
Методы
t
С помощью этого метода вы можете получить текст на выбранном языке.
Например:
hello-user = Привет, {$userName}!context.t("hello-user", { userName: "Анна" }); // Привет, Анна!setLocale
Вы можете установить язык пользователя методом setLocale.
WARNING
На данный момент нет интеграции с сессиями, поэтому после сообщения язык снова станет таким, какой указан в defaultLocale
bot.command("start", async (context) => {
context.setLocale("ru");
return context.send(
context.t("shared-photos", {
userName: "Анна",
userGender: "female",
photoCount: 3,
})
);
});Типо-безопасность
Вы можете использовать этот плагин с fluent2ts, который генерирует типы TypeScript из ваших файлов .ftl. См. инструкцию по использованию.
Npm:
npx fluent2tsBun:
bunx fluent2tsYarn:
yarn dlx fluent2tsPnpm:
pnpm exec fluent2tsВ результате вы получите сгенерированный файл locales.types.ts в папке src, который экспортирует интерфейс TypedFluentBundle. Устанавливаем этот тип как дженерик для плагина i18n - и вот у нас есть типо-безопасность!
import type { TypedFluentBundle } from "./locales.types.js";
import { Bot } from "gramio";
import { i18n } from "@gramio/i18n/fluent";
const bot = new Bot(process.env.BOT_TOKEN as string)
// или .extend(i18n(createFluentClient<TypedFluentBundle>()))
.extend(i18n<TypedFluentBundle>())
.command("start", async (context) => {
const firstMsg = context.t("hello-user");
//
//
//
const secondMsg = context.t("shared-photos", {
userName: "Анна",
userGender: "female",
photoCount: 3,
});
//
//
//
//
return context.send(secondMsg);
})
.onError(console.error)
.onStart(console.log);
bot.start();