一个小问题Phabricator的部分界面无法本地化
最近我进行了一些Phabricator本地化的工作,在这个过程中,我发现Phabricator的一小部分界面始终无法翻译,即使我在PhabricatorCNChineseTranslation.php中添加了相应的翻译项。
Phabricator是通过pht函数实现本地化的,pht(‘User’)将会返回User的本地化翻译,如果没有可用的翻译,那么就会返回’User’自身。
如果我们深入Phabricator的代码,我们不难发现,上图中的”Tag”之所以无法翻译,是因为这个”Tag”来源于PhabricatorProjectIconSet类的如下代码。
private static function getIconSpecifications() {
return PhabricatorEnv::getEnvConfig('projects.icons');
}
上述代码其实是从Phabricator的配置项projects.icons中载入”Tag”, “Project”等配置。 这个配置项其实就是一串JSON
不难看出,无论如何,载入projects.icons的时候,Phabricator不会对projects.icons这个配置项的内容进行任何pht操作,这也就导致”Tag”等文本不会被翻译了。
我在自己的本地代码中,对PhabricatorProjectIconSet进行了如下改动,即在getIconSpec和getIconName函数上加上pht的调用。这样就可以实现本地化翻译了。但是,这样的改动是不符合Phabricator的pht规范的,即传入给pht的参数必须是scala string value,而由于下面的代码的缘故,我们并不能保证pht($value)的$value是一个scala value,理论上也可能是一个array(projects.icons是一个可以任意修改的配置项,所以我们并不能保证$value是scala),所以,我的代码是不能通过arc lint的。
public static function getIconName($key) {
$spec = self::getIconSpec($key);
return pht(idx($spec, 'name', null));
}
private static function getIconSpec($key) {
$icons = self::getIconSpecifications();
foreach ($icons as $icon) {
if (idx($icon, 'key') === $key) {
$spec_local = array();
foreach ($icon as $key => $value) {
if ($key == 'name') {
$spec_local['name'] = pht($value);
} else {
$spec_local[$key] = $value;
}
}
return $spec_local;
}
}
return array();
}
简而言之,上述的代码只是一个补丁,仍然不是最好的方案,但是至少能够保证翻译了。