跳转至

I18n(国际化)

ll/api/i18n/ · 通用

概述

I18n 模块提供了国际化和本地化支持,采用简单的键值翻译系统。支持从文件加载翻译、运行时更新翻译,以及通过用户自定义字面量进行编译期检查的格式化字符串。

头文件

头文件 说明
ll/api/i18n/I18n.h I18n 管理器和翻译字面量

核心类

I18n

翻译管理器单例。

C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
namespace ll::i18n {
class I18n {
public:
    Expected<> load(std::filesystem::path const& path) noexcept;
    void clear();
    void set(std::string_view localeCode, std::string_view key, std::string_view value);
    std::string_view get(std::string_view key, std::string_view localeCode) const;
};

I18n& getInstance();
std::string_view getDefaultLocaleCode();
}

用户自定义字面量

_tr — 使用默认语言翻译

C++
1
2
3
4
using namespace ll::literals::i18n_literals;

auto msg = "hello.world"_tr();           // 无参数
auto greeting = "hello.user"_tr("Alice"); // 带格式化参数

_trl — 使用指定语言翻译

C++
1
2
auto msg = "hello.world"_trl("zh");           // 中文
auto greeting = "hello.user"_trl("en", "Bob"); // 英文带参数

使用方法

加载翻译

load() 函数接受目录路径JSON 文件路径

方式 1:目录中的独立语言文件

在目录中为每种语言创建单独的 JSON 文件:

Text Only
1
2
3
4
lang/
├── en.json
├── zh.json
└── ja.json

每个文件仅包含该语言的翻译:

en.json:

JSON
1
2
3
4
5
{
  "hello.world": "Hello, World!",
  "hello.user": "Hello, {}!",
  "item.count": "You have {} items"
}

zh.json:

JSON
1
2
3
4
5
{
  "hello.world": "你好,世界!",
  "hello.user": "你好,{}!",
  "item.count": "你有 {} 个物品"
}

加载目录:

C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#include "ll/api/i18n/I18n.h"
#include "ll/api/mod/Mod.h"

void loadTranslations(ll::mod::Mod& mod) {
    auto& i18n = ll::i18n::getInstance();
    // 从目录加载所有语言文件
    auto result = i18n.load(mod.getLangDir());
    if (!result) {
        mod.getLogger().error("加载翻译失败");
    }
}

方式 2:包含所有语言的单个 JSON 文件

创建一个 JSON 文件,以语言代码作为顶层键:

translations.json:

JSON
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
{
  "en": {
    "hello.world": "Hello, World!",
    "hello.user": "Hello, {}!",
    "item.count": "You have {} items"
  },
  "zh": {
    "hello.world": "你好,世界!",
    "hello.user": "你好,{}!",
    "item.count": "你有 {} 个物品"
  }
}

加载文件:

C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#include "ll/api/i18n/I18n.h"
#include "ll/api/mod/Mod.h"

void loadTranslations(ll::mod::Mod& mod) {
    auto& i18n = ll::i18n::getInstance();
    // 加载包含所有语言的单个文件
    auto result = i18n.load(mod.getLangDir() / "translations.json");
    if (!result) {
        mod.getLogger().error("加载翻译失败");
    }
}

使用翻译

C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#include "ll/api/i18n/I18n.h"

using namespace ll::literals::i18n_literals;

void greetPlayer(std::string const& name) {
    // 使用默认语言
    auto msg = "hello.user"_tr(name);
    // msg == "Hello, Alice!" 或 "你好,Alice!" 取决于默认语言
}

void showItemCount(int count) {
    auto msg = "item.count"_tr(count);
}

运行时更新翻译

C++
1
2
3
4
5
6
7
#include "ll/api/i18n/I18n.h"

void addTranslation() {
    auto& i18n = ll::i18n::getInstance();
    i18n.set("en", "custom.key", "Custom message");
    i18n.set("zh", "custom.key", "自定义消息");
}

显式选择语言

C++
1
2
3
4
5
6
using namespace ll::literals::i18n_literals;

void showInChinese() {
    auto msg = "hello.world"_trl("zh");
    // msg == "你好,世界!"
}

相关模块