HTML inside __() or _e() language translation string

What is the proper approach to building translation strings?

For example,

Read More
echo __( 'Hello ' . $first . ' you owe me money.' );
echo __( '<div><p>Top: ' . $t_margin . '</p>' . '<p>Bottom: ' . $b_margin . '</p></div>' )

Is it OK to add the strings and/or HTML or should it be done first and then run through translation like:

$html = '<div><p>Top: ' . $t_margin . '</p>' . '<p>Bottom: ' . $b_margin . '</p></div>';
echo __( $html ); 

Related posts

2 comments

  1. There is a second argument in the __() function. It should be set to the domain you are are using for your plugin or theme. In the examples below I use 'text_domain'. Your domain string should be unique. It should not match any other domain string. Not using a text domain argument defaults to 'default' the WordPress domain name. See the link for more details.

    Always use the string ('text_domain'). Never use a variable, function or constant with the string in it. Most (all?) translation programs will not see it without the string there.

    Your code:

    echo __( 'Hello ' . $first . ' you own me money.' );
    

    Do not include variables in the string.

    A better way:

    echo sprintf( __( 'Hello %s you own me money.', 'text_domain' ), $first );
    

    Or just:

    printf( __( 'Hello %s you own me money.', 'text_domain' ), $first );
    

    The %s placeholder tells the human translator that a string is going in there. Use %d for numbers. There are also other placeholders.

    (This sentence is grammatically incorrect English. Use either 'Hello %s, you owe me money.' or 'Hello %s, you own my money.' depending on the meaning you were intending.)


    Your code:

    $html = '<div><p>Top: ' . $t_margin . '</p>' . <p>Bottom: ' . $b_margin . '</p></div>';
    

    Don’t translate HTML. It is the same in any language.

    A better way:

    $html = sprintf( '<div><p>%s</p><p>%s</p></div>', __( 'Top: ', 'text_domain' ) .  $t_margin, __( 'Bottom: ', 'text_domain' ) . $b_margin );
    

    Or break it into multiple lines:

    $html = sprintf(
        '<div><p>%s</p><p>%s</p></div>',
        __( 'Top: ', 'text_domain' ) .  $t_margin,
        __( 'Bottom: ', 'text_domain' ) . $b_margin
    );
    

    If it is not apparent what Top and Bottom are you might use the _x() to explain the context of these terms.


    You can find other translation cases here: Internationalization: You’re probably doing it wrong

  2. I won’t address the issue of variables in the string since it’s already been said.

    You want to keep your string static, meaning that the content won’t change. You also want to keep out unnecessary HTML.

    __( '<p>Hello World!</p>' );
    __( '<h1>Hello World!</h1>' );
    

    The above will take up two rows in your table for what is essentially the same text. They can be rewritten as:

    '<p>' . __( 'Hello World!' ) . '</p>'
    '<h1>' . __( 'Hello World!' ) . '</h1>'
    

    Reducing it to a single row.

    Sometimes HTML in the text is unavoidable. Take for example:

    __( 'You currently owe <b>%s</b> dollars' );
    

    Since languages are grammatical, splitting the text would cause problems for whoever is translating.

    Rule of thumb. HTML text formatting tags mid sentence are OK. Sentences beginning and ending with HTML just waste space.

Comments are closed.