> For the complete documentation index, see [llms.txt](https://eric2788.gitbook.io/eldependenci/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://eric2788.gitbook.io/eldependenci/advanced-tutorial/config-operation/i18n.md).

# 多語言文件

多語言文件，指一個訊息集合下可有多種不同的語言，可用作 [i18n](https://openhome.cc/Gossip/Rails/i18n.html)。

假設你的插件 jar 內有兩種語言文件:

{% code title="Langs/en-us.yml" %}

```yaml
prefix: "[ELD] "
first: "This is the first message"
second: "This is the second message"
third: "This is the third message"
```

{% endcode %}

{% code title="Langs/zh-tw\.yml" %}

```yaml
prefix: "[ELD] "
first: "這是第一則信息"
second: "這是第二則訊息"
third: "這是第三則信息"
```

{% endcode %}

則創建一個繼承 `GroupLangConfiguration` 的類，並配置如下:

```java
@GroupResource(
        folder = "Langs", // 語言文件的文件夾
        preloads = {"en-us", "zh-tw"} // 複製這兩個文件從 jar 內到 插件資料夾
)
@DefaultLanguage("en-us") // 定義默認語言
@Prefix(path = "prefix") // 定義prefix路徑
public class TesterMultiLang extends GroupLangConfiguration {
}

```

註冊如下:

```java
    @Override
    public void bindServices(ServiceCollection serviceCollection) {
        serviceCollection.addMultipleLanguages(TesterMultiLang.class); // 註冊多語言文件
    }
```

## 使用

註冊完成後，則可注入 `GroupLang<T>` 服務並標註 `@InjectPool` 來進行獲取:

```java
@Commander(
        name = "lang",
        description = "test language command"
)
public class TestLanguageCommand implements CommandNode {

    @InjectPool
    private GroupLang<TesterMultiLang> multiLangGroupLang;

    @CommandArg(order = 1)
    private String language;

    @Override
    public void execute(CommandSender commandSender) {
        Optional<TesterMultiLang> multiLangOpt = multiLangGroupLang.getByLocale(language);
        if (multiLangOpt.isEmpty()){
            commandSender.sendMessage("unknown language");
            return;
        }
        var multiLang = multiLangOpt.get();
        commandSender.sendMessage(multiLang.getLang().get("first"));
        commandSender.sendMessage(multiLang.getLang().get("second"));
        commandSender.sendMessage(multiLang.getLang().get("third"));
    }
}
```

{% hint style="success" %}
在上述的指令中, 輸入 /test lang en-us 將出現 en-us.yml 文件內的訊息，輸入 /test lang zh-tw 則出現 zh-tw\.yml 文件內的訊息。若查無文件，則發送 `unknown language 。`
{% endhint %}

在使用上，你會發現跟 [文件池配置](/eldependenci/advanced-tutorial/config-operation/configuration-pool.md) 其實很相同。但兩者的分別在於，`GroupLang<T>` 只提供了唯讀性質的操作。其源碼如下：

```java
public interface GroupLang<T extends GroupLangConfiguration> {

    /**
     * 根據 語言 id 獲取語言文件實例
     * @param locale 語言 id
     * @return 語言文件實例
     */
    Optional<T> getByLocale(String locale);

    /**
     * 獲取默認語言文件實例
     * @return 默認語言文件實例
     */
    T getDefault();

    /**
     * 根據 語言 id 清除快取
     * @param locale 語言 id
     */
    void fetchById(String locale);

    /**
     * 清除所有快取
     */
    void fetch();


}
```

{% hint style="warning" %}
跟 `GroupConfig<T>`同樣，`GroupLang<T>` 本身的操作也不是異步的，你需要自行實作異步。但它本身亦有快取功能，能大程度上加快二次獲取。

有時候你可能需要手動去獲取特定類型的 `GroupLang<T>`，這時候你應該使用[文件池服務](/eldependenci/references/internal-api-services/config-pool-service.md)。
{% endhint %}

## 使用為 i18n&#x20;

你可以透過多語言文件實作 i18n 的服務，範例如下:

{% code title="I18nService.java" %}

```java
public interface I18nService {
    
    void sendMessage(Player player, String path);
    
    void switchLanguage(Player player, String lang);
    
}
```

{% endcode %}

{% code title="I18nServiceImpl.java" %}

```java
public class I18nServiceImpl implements I18nService {

    private final Map<UUID, String> languageMap = new HashMap<>(); // 語言儲存資料庫，你應實作離線儲存

    @InjectPool
    private GroupLang<TesterMultiLang> languagePool;

    // 根據玩家的語言發送訊息
    @Override
    public void sendMessage(Player player, String path) {
        String lang = languageMap.getOrDefault(player.getUniqueId(), "en-us");
        var langConfig = languagePool.getByLocale(lang).orElseGet(() -> {
            player.sendMessage("由於沒有你的語言 (".concat(lang).concat("), 因此使用回默認語言 en-us"));
            return languagePool.getDefault();
        }); // 發送玩家所使用的語言的訊息, 若無則自動返回默認語言文件
        player.sendMessage(langConfig.getLang().get(path));
    }

    // 切換語言
    @Override
    public void switchLanguage(Player player, String lang) {
        languageMap.put(player.getUniqueId(), lang);
    }
}
```

{% endcode %}

{% hint style="info" %}
記得別忘了註冊！
{% endhint %}
