PHP: How can you use line breaks in Poedit
Asked Answered
P

2

5

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?

Passifloraceous answered 10/2, 2014 at 16:33 Comment(0)
D
5

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.

Dorty answered 11/2, 2014 at 10:10 Comment(4)
Hey :) Thank you for your answer. You are right the function works great if you add manually \n into the textarea in poedit, but poedit doesn´t insert those \n if you click enter to make a new line. So this is not a good solution because the translator should not enter the line breaks manually (even <break> or \n)Passifloraceous
@Passifloraceous I've just edited my answer to correct plain wrong information about line feeds in Poedit. Sorry for the inconvenience.Rambler
Ok, thanks! Is there somebody else who can answer this question?Passifloraceous
@Passifloraceous I think you should edit the question and explain what you miss in current answers. As it's now, it only wonders if you need to use HTML and it's clear you don't (and br is not HTML; <br> is).Rambler
R
4

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
)
Reeding answered 10/2, 2014 at 16:38 Comment(2)
See the post below, unfortunately this is not a good solution because you have to enter \n manuallyPassifloraceous
The answer should also work with linebreaks inside your translation file. I have edited my answer, first to show how it works and additionally to use the nl2br method in PHP which already handles the platform independent replacement of the linebreaks to HTML-tags.Reeding

© 2022 - 2024 — McMap. All rights reserved.