Translating WP with __() and sprintf()

14,079

Solution 1

echo sprintf(__("text %s", 'your__text_domain'), $data);

Solution 2

A.,

In your code:

$translation = sprintf( __( '%s', 'textdomain' ), get_color() );

the __() functions checks for a translation of the string '%s' - of which you probably have no translation - and then replaces '%s' with the result of get_color(). So the value for get_color() never passes the translation function.

I am not sure what the right solution is here, maybe just forget about Theme Check in this case.

Solution 3

I'm surprised no one mentioned the "translators" comment, that tells the translator what each variable in the sprintf is. Examples:

sprintf(
    /* translators: %s: Name of a city */
    __( 'Your city is %s.', 'my-plugin' ),
    $city
);

sprintf(
     /* translators: 1: Name of a city 2: ZIP code */
    __( 'Your city is %1$s, and your zip code is %2$s.', 'my-plugin' ),
    $city,
    $zipcode
);

See: https://developer.wordpress.org/plugins/internationalization/how-to-internationalize-your-plugin/#variables

Solution 4

Many translation tools that extract translatable strings will look for string literals, like this:

$translation = __( 'red', 'textdomain' );

It's a safe bet* that the Theme Check plugin is alerting you to the fact that your dynamic string will not be extracted by such tools. This is because the code won't be executed during extraction, hence the expression get_color() will not be evaluated into a translatable string.

If you don't care about compatibility with string extraction tools, then just leave your code as per your first example (The second example is wrong as already pointed out).

If you do want your code to work with translation tools, then I suggest you create a dummy PHP file containing all possible colour values. (assuming that list is finite). Your file would look something like this:

<?php
__('red', 'textdomain' );
__('blue', 'textdomain' );
// and so on..

Then, if you want to stop the actual translation call producing "Theme Check" errors you'll have to refactor it into something that won't get picked up. Something like this would get missed by most extractors:

$translation = call_user_func( '__', get_color(), 'textdomain' );

* Worth noting that the author of Theme Check is a core WordPress contributor and quite vocal about doing WordPress i18n correctly.

Share:
14,079
D. A.
Author by

D. A.

Updated on June 04, 2022

Comments

  • D. A.
    D. A. almost 2 years

    I'm trying to translate WP theme. I have this code:

    $translation = __( get_color(), 'textdomain' );
    

    It works, I get color dynamically from get_color() function, and it translates well. But when I use "Theme Check" plugin I get error for this code.

    I need to use this instead:

    $translation = sprintf( __( '%s', 'textdomain' ), get_color() );
    

    But in that case my placeholder %s doesn't translates, and I get original color name (not translated).

    What I'm doing wrong? Thank you.