Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP: How can you use line breaks in Poedit

I am using poedit to translate my gettext strings. I´m using ID´s to translate, so for example the following ID:

"msg_forgot_pw"

would be translated to:

"I have forgot my password"

The string will be printed with echo, so the string should be valid HTML. Currently I´m using <br> to make new lines within the translation in Poedit. We already found out that you can use \n in the translation and than use a translation-function like Álvaro G. Vicario made. The only problem here is, that you must enter \n manually in Pedit, because it doesn´t replace a enter to a \n. So is there a way to make new lines in the output of those translation strings without putting <br> or \n manually into it?

like image 730
user3292653 Avatar asked Feb 10 '14 16:02

user3292653


2 Answers

The PO catalogue format itself does not restrict translations to be one-liners but you need to use proper markup:

#: example.php:2
msgid "__multi_line_example__"
msgstr ""
"One line\n"
"Two lines\n"
"Three lines\n"

Unluckily, the popular Poedit program does not make it easy: you can type actual new lines with the Enter key but they are silently discarded on save! You can insert new lines even with Poedit but you need to type a \n escape sequence manually:

New lines in Poedit

(No idea about what other graphical tools do.)

The string will be printed with echo, so the string should be valid HTML.

IMHO, accepting HTML code from translators is kind of risky. You give them too much power to break the app badly. It's normally safer to only accept plain text and escape it properly when injecting it in HTML context, e.g.:

<p><?php echo htmlspecialchars(_('msg_forgot_pw')); ?></p>

This also makes the string usable in non-HTML context (e.g., a plain text e-mail message).

My advice is that:

  1. The translatable string contains plain text
  2. You add <br> tags yourself when printing

    <p><?php echo nl2br(htmlspecialchars(_('msg_forgot_pw'))); ?></p>
    

This is pretty lengthy so I suggest writing wrappers:

/**
 * 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');
}

Edit: The answer to the updated question is "no, not with Poedit". You'll have to live with that or find another tool.

like image 179
Álvaro González Avatar answered Oct 12 '22 20:10

Álvaro González


A possibility would be to use "normal" linebreaks \n, \r or \r\n (depends on your platform) and replace them in PHP with the <br /> tag - there is already a PHP function for that: nl2br. I am not aware of your code design, but generally you can do this in the method you translate the keys:

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)
}

and call it via:

echo translation("msg_forgot_pw");

Your translation file have to look something like this:

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
)
like image 3
Flixer Avatar answered Oct 12 '22 18:10

Flixer