Плагин i18n
Плагин i18n
для GramIO.
Этот плагин помогает добавить многоязычность в ваши боты с помощью синтаксиса Fluent.
Вы можете настроить типо-безопасность для него.
Плагин i18n
для GramIO.
Этот плагин предоставляет удобный способ добавить многоязычность в ваши боты! Его можно использовать без GramIO, но он всегда будет учитывать его особенности.
IMPORTANT
Начиная с версии 1.0.0
, у нас есть два способа написания локализации: I18n-in-TS
и Fluent
Установка
npm install @gramio/i18n
bun add @gramio/i18n
yarn add @gramio/i18n
pnpm add @gramio/i18n
npm install @gramio/i18n @fluent/bundle
bun add @gramio/i18n @fluent/bundle
yarn add @gramio/i18n @fluent/bundle
pnpm 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 fluent2ts
Bun:
bunx fluent2ts
Yarn:
yarn dlx fluent2ts
Pnpm:
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();