PHP: How can you use line breaks in Poedit

user3292653 picture user3292653 · Feb 10, 2014 · Viewed 7.7k times · Source

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?

Answer

&#193;lvaro Gonz&#225;lez picture Álvaro González · Feb 11, 2014

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.