CakePHP/2 中的伪定位
Pseudolocalization in CakePHP/2
我正在调整现有应用程序以支持多种语言,我想实施 pseudolocalization,即制作本地化字符串:
<?php echo h(__('Edit program settings')); ?>
...脱颖而出:
[!!! εÐiţ Þr0ģЯãm səTτıИğ§ !!!]
...所以我可以快速发现遗漏并检测潜在的布局问题。
除非我错了,否则该功能不是内置的,也没有第三方插件。我的机会有多大?
我觉得一个明智的方法是扩展 I18n
并覆盖 I18n::translate()
。但是我不是特别熟悉 CakePHP 的内部结构,我不确定如何让 __()
和家人使用我的扩展 class.
另一方面,lib\Cake\basics.php
中的函数包含在 function_exists()
调用中,所以我想我可以编写自己的版本...
我欢迎任何建议。
理想的技术是能够定义自定义 class:
class CustomI18n extends I18n {
public static function translate($singular, $plural = null, $domain = null, $category = 6, $count = null, $language = null) {
}
}
… 并指示 CakePHP 使用我的自定义 class 而不是原始的。这将与例如一致视图助手的工作方式。
不幸的是,我认为这不可能完成¹,因为视图中的 $this->Html
是动态的 属性 但 __()
包含硬编码的 class 姓名:I18n::translate($singular)
.
¹ 是的,almost everything可以做到。你知道我的意思:)
因为它只是一个不适合生产的辅助工具,所以您总是可以求助于一个并非真正针对 CakePHP 的快速而肮脏的 hack:
将您感兴趣的 lib\Cake\basics.php
中的函数重写到您选择的文件中,通常是以下划线开头的函数:__()
、_n()
, ...
function __($singular, $args = null) {
if (!$singular) {
return;
}
$singular = pseudotranslation($singular); // <---------------------
App::uses('I18n', 'I18n');
$translated = I18n::translate($singular);
if ($args === null) {
return $translated;
} elseif (!is_array($args)) {
$args = array_slice(func_get_args(), 1);
}
return vsprintf($translated, $args);
}
确保您没有破解 vsprintf
密码。
使用 auto_prepend_file 在 CakePHP 启动之前加载文件。理想情况下,将其设置在您的开发箱中。
这样做的好处是不引人注目。您可以很容易地启用或禁用 [=19=] 或者您可以在您的前置脚本中处理它。
或者,CakePHP 允许 override 大多数 classes,因此您可以将 /lib/Cake/I18n/I18n.php
复制为 /app/Lib/I18n/I18n.php
并根据自己的喜好调整 I18n::translate()
。但是我发现这不太方便:如果您升级 CakePHP,您仍然必须维护系统文件的自定义副本,并且没有简单的机制可以在运行时禁用伪本地化,因为 CakePHP 将始终使用存在的文件。
我正在调整现有应用程序以支持多种语言,我想实施 pseudolocalization,即制作本地化字符串:
<?php echo h(__('Edit program settings')); ?>
...脱颖而出:
[!!! εÐiţ Þr0ģЯãm səTτıИğ§ !!!]
...所以我可以快速发现遗漏并检测潜在的布局问题。
除非我错了,否则该功能不是内置的,也没有第三方插件。我的机会有多大?
我觉得一个明智的方法是扩展 I18n
并覆盖 I18n::translate()
。但是我不是特别熟悉 CakePHP 的内部结构,我不确定如何让 __()
和家人使用我的扩展 class.
另一方面,lib\Cake\basics.php
中的函数包含在 function_exists()
调用中,所以我想我可以编写自己的版本...
我欢迎任何建议。
理想的技术是能够定义自定义 class:
class CustomI18n extends I18n {
public static function translate($singular, $plural = null, $domain = null, $category = 6, $count = null, $language = null) {
}
}
… 并指示 CakePHP 使用我的自定义 class 而不是原始的。这将与例如一致视图助手的工作方式。
不幸的是,我认为这不可能完成¹,因为视图中的 $this->Html
是动态的 属性 但 __()
包含硬编码的 class 姓名:I18n::translate($singular)
.
¹ 是的,almost everything可以做到。你知道我的意思:)
因为它只是一个不适合生产的辅助工具,所以您总是可以求助于一个并非真正针对 CakePHP 的快速而肮脏的 hack:
将您感兴趣的
lib\Cake\basics.php
中的函数重写到您选择的文件中,通常是以下划线开头的函数:__()
、_n()
, ...function __($singular, $args = null) { if (!$singular) { return; } $singular = pseudotranslation($singular); // <--------------------- App::uses('I18n', 'I18n'); $translated = I18n::translate($singular); if ($args === null) { return $translated; } elseif (!is_array($args)) { $args = array_slice(func_get_args(), 1); } return vsprintf($translated, $args); }
确保您没有破解
vsprintf
密码。使用 auto_prepend_file 在 CakePHP 启动之前加载文件。理想情况下,将其设置在您的开发箱中。
这样做的好处是不引人注目。您可以很容易地启用或禁用 [=19=] 或者您可以在您的前置脚本中处理它。
或者,CakePHP 允许 override 大多数 classes,因此您可以将 /lib/Cake/I18n/I18n.php
复制为 /app/Lib/I18n/I18n.php
并根据自己的喜好调整 I18n::translate()
。但是我发现这不太方便:如果您升级 CakePHP,您仍然必须维护系统文件的自定义副本,并且没有简单的机制可以在运行时禁用伪本地化,因为 CakePHP 将始终使用存在的文件。