Skip to content

修复和改进 I18n 的多语言文件加载逻辑#1860

Open
luoingly wants to merge 2 commits intotypecho:masterfrom
luoingly:master
Open

修复和改进 I18n 的多语言文件加载逻辑#1860
luoingly wants to merge 2 commits intotypecho:masterfrom
luoingly:master

Conversation

@luoingly
Copy link
Copy Markdown

该 Pull Request 旨在解决 I18n 实现中的两个关键问题:

  1. 多语言文件加载问题

    当前实现中,GetTextMulti::translate 遍历所有语言文件的 handler,期望通过 $count 判断是否找到翻译。若 $count != -1 则终止循环,否则继续检查后续文件。

    而不论是被标记短路 (short_circuit) 或是启用缓存 (enable_cache) 的情况下,GetText::translateGetText::ngettext 方法都未正确设置 $num 的值,导致 GetTextMulti 在遍历翻译文件时提前终止。

    修改后,在这两个条件中 $num 会被显式设置为 -1(未找到)或 0(找到),确保能够通过 $count 判断是否找到翻译,使得所有翻译文件都能被正确遍历。

  2. 翻译文件加载时机问题

    在加载主题的 function.php 时,I18n 可能尚未初始化,而 I18n::init 是私有方法,无法直接调用。针对此问题参考了 I18n::translateI18n::ngettext 的实现,对 I18n::addLang 进行了修改。

    修改后,在 I18n::addLang 中会尝试自动调用 init(),并且再确认在未能载入的情况下不进一步尝试调用 GetTextMulti::addFile

修改后,对于主题或是插件的开发者,都可以经由下列方法实现 I18n(以主题为例):

  • 通过 \Typecho\I18n::addLang

    在主题的 function.php 中,可以通过:

    \Typecho\I18n::getLang()

    获取到当前挂载的语言文件,如果其值存在则证明用户的语言设置为了 zh_CN 之外的值,那么就可以通过 basename 进一步获取到形如 en_US.mo 的内容,开发者可以自行判断是否存在相应的 I18n 支持,并且通过:

    \Typecho\I18n::addLang(dirname(__FILE__) . '/lang/en_US.mo');

    这样的方法进行挂载。

  • 通过 \Utils\Helper::lang

    \Utils\Helper::lang('../../usr/themes/<theme_folder>/');

    该方法会自行寻找 <theme_folder>/lang 目录下是否存在用户所选语言的 .mo 文件并进行挂载。

- 修改了 `GetText::translate` 和 `GetText::ngettext`,在启用缓存时显式设置 `$num`。
- 确保未找到翻译时 `$num` 设置为 `-1`,使 `GetTextMulti` 能够继续搜索后续文件。
- 修改了 `I18n::addLang`,在添加翻译文件时自动调用 `init()`。
- 确保初始化后再调用 `addFile`,避免抛出异常。
Comment thread var/Typecho/I18n.php
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这一个有待商榷,其实我预想中更好的做法是不需要手动添加语言文件,只需要把语言文件放置在对应的目录就会自动加载。之前的实现比较粗糙。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants