use*_*653 5 php gettext poedit
我正在使用 poedit 来翻译我的 gettext 字符串。我正在使用 ID 进行翻译,例如以下 ID:
"msg_forgot_pw"
将被翻译为:
“我忘记了密码”
该字符串将使用 echo 打印,因此该字符串应该是有效的 HTML。目前我正在使用<br>Poedit 在翻译中创建新行。我们已经发现您可以\n在翻译中使用,而不是使用诸如Álvaro G. Vicariomade 之类的翻译功能。这里唯一的问题是,您必须\n在 Pedit 中手动输入,因为它不会将输入替换为\n. 那么有没有办法在这些翻译字符串的输出中创建新行而无需放入<br>或\n手动输入?
PO 目录格式本身并不限制翻译为单行,但您需要使用正确的标记:
#: example.php:2
msgid "__multi_line_example__"
msgstr ""
"One line\n"
"Two lines\n"
"Three lines\n"
Run Code Online (Sandbox Code Playgroud)
不幸的是,流行的 Poedit 程序并不容易:您可以使用 键键入实际的新行Enter,但它们在保存时会被默默丢弃!即使使用 Poedit也可以插入新行,但需要\n手动输入转义序列:

(不知道其他图形工具的作用。)
该字符串将用 echo 打印,因此该字符串应该是有效的 HTML。
恕我直言,接受翻译者的 HTML 代码是有风险的。你给了他们太多的权力来严重破坏应用程序。通常,只接受纯文本并在 HTML 上下文中注入时正确转义它更安全,例如:
<p><?php echo htmlspecialchars(_('msg_forgot_pw')); ?></p>
Run Code Online (Sandbox Code Playgroud)
这也使得该字符串可以在非 HTML 上下文中使用(例如,纯文本电子邮件消息)。
我的建议是:
<br>打印时自己添加标签
<p><?php echo nl2br(htmlspecialchars(_('msg_forgot_pw'))); ?></p>
Run Code Online (Sandbox Code Playgroud)这相当冗长,所以我建议编写包装器:
/**
* Fetches translation as HTML (block with line feeds)
*
* @param string $msg_id Message ID
* @return string HTML
*/
function p($msg_id){
return nl2br(htmlspecialchars(_($msg_id), ENT_COMPAT | ENT_HTML401, 'UTF-8'), false);
}
/**
* Fetches translation as HTML (single line)
*
* @param string $msg_id Message ID
* @return string HTML
*/
function l($msg_id){
return htmlspecialchars(_($msg_id), ENT_COMPAT | ENT_HTML401, 'UTF-8');
}
Run Code Online (Sandbox Code Playgroud)
编辑:更新问题的答案是“不,不是 Poedit”。您将不得不忍受这一点或寻找其他工具。
一种可能是使用“普通”换行符\n,\r或者\r\n(取决于您的平台)并在 PHP 中用标签替换它们<br />- 已经有一个 PHP 函数可以做到这一点:nl2br。我不知道您的代码设计,但通常您可以在翻译键的方法中执行此操作:
function translate($key){
// do something to get the translation from the file and store it in some variable ($translation in this case)
return nl2br($translation)
}
Run Code Online (Sandbox Code Playgroud)
并通过以下方式调用它:
echo translation("msg_forgot_pw");
Run Code Online (Sandbox Code Playgroud)
您的翻译文件必须如下所示:
array(
// you can use a \n, \r, \r\n tag
"msg_forgot_pw" => "I have forgot \nmy password",
// or you can simply add a linebreak
"msg_forgot_pw2" => "I have forgot
my password",
// ... more entries
)
Run Code Online (Sandbox Code Playgroud)