skip to Main Content

I’m creating a new plugin. I generated the PO and MO files for my plugin using POedit and I followed all the steps as described on https://developer.wordpress.org/plugins/internationalization/how-to-internationalize-your-plugin/, from writing a perfect header in the main plugin file till adding php code in the same file in order to load text domain and the MO file.

When I change the site language from English to French the plugin still displaying EN strings.

What could be the issue? Is it because the plugin is not on wordpress.org yet?

Here’s my laptop config :

locahost : wampserver
Windows 10
Php version : 8.1

Thanks in advance!

Note:

In the main plugin file, in order to load the PO and MO files, I put this :

/**
 * wpdocs_load_textdomain() loads Text Domain for the translation
 */
function wpdocs_load_textdomain() {
    load_plugin_textdomain( 'str-sticky-header', false, dirname( plugin_basename( __FILE__ ) ) . '/lang' ); 
}


/**
 * my_plugin_load_my_own_textdomain( $mofile, $domain )  loads the MO file for the translation
 * @param $mofile
 * @param $domain
 */
function my_plugin_load_my_own_textdomain( $mofile, $domain ) {
    if ( 'str-sticky-header' === $domain && false !== strpos( $mofile, WP_LANG_DIR . '/plugins/' ) ) {
        $locale = apply_filters( 'plugin_locale', determine_locale(), $domain );
        $mofile = WP_PLUGIN_DIR . '/' . dirname( plugin_basename( __FILE__ ) ) . '/lang/' . $domain . '-' . $locale . '.mo';
    }
    die($mofile);
    return $mofile;
}

add_action( 'init', 'wpdocs_load_textdomain' );
add_filter( 'load_textdomain_mofile', 'my_plugin_load_my_own_textdomain', 10, 2 );

The die($mofile) function is displaying the right MO file. Is the error in the translation itself?

2

Answers


  1. Chosen as BEST ANSWER

    Here's the solution : I'm talking about my case here, When I added the Text Domain Name to Gettext functions in interface.php file, I used this command line : php add-textdomain.php TextDomainNameOfThePlugin PathToInterfaceFile/interface.php > tdn.php , So I generated tdn.php as you can see in that command line, and constructed my POT, PO and MO files based on this UNUSED NEW FILE, and I forgot to either rename tdn.php to interface.php (and delete the old interface.php) so I can use it, or to copy its content and paste in into interface.php file that didn't contain Text Domain Name in its Gettext functions.

    So now, I just copied tdn.php content to interface.php, and the translation works perfectly.

    Thanks @DanieleAlessandra !


  2. all the code you shared with us is correct. You do not even need the function my_plugin_load_my_own_textdomain but I assume that it is used for debugging only.

    The problem should be in a part of your code that we do not see. If well configured, translations must work on your local environment, even if the plugin is not yet distributed.

    Check the following things:

    1. Does your .mo file exist? You said that when you execute die($mofile) you see something that looks like the right file, please check twice with something like is_file($mofile). If the file is missing, in fact, translation fails silently.
    2. Is the name correct? Your .mo file must be named like this <text_domain>-<locale>.mo, in your case the file must be named str-sticky-header-fr_FR.mo. This should be already this way, because you are seeing the name in my_plugin_load_my_own_textdomain
    3. Is your file valid? It may be corrupted, what are you using to generate translatio files? Try this online free resource https://localise.biz/free/poeditor (not mine, I googled it).

    While trying to figure out your issue, I wrote a simple PHP script that – once placed in a directory along your .mo translations – checks if they work. Hopefully this script could help you and other people investigating similar issues. You may find it here: https://github.com/DanieleAlessandra/wp-translation-check


    [Edit: adding a snippet to investigate translation loading state]

    After several attempts we still don’t know if your translation file has being loaded. Please add the following snippet anywhere to have an output of loaded strings for the current language in your text domain:

    $translations = get_translations_for_domain( 'str-sticky-header' );
    echo('<pre>');
    var_dump($translations->entries);
    

    The perfect place to put this snippet is immediatelu after a failed translation, so you can have the un-translated string in front of your eyes along with this snippet output.

    The output should be something similar to the following:

    array(1) {
      [0]=>
      object(Translation_Entry)#2914 (9) {
        ["is_plural"]=>
        bool(false)
        ["context"]=>
        NULL
        ["singular"]=>
        string(36) "Hello, this is the original message!"
        ["plural"]=>
        NULL
        ["translations"]=>
        array(1) {
          [0]=>
          string(43) "Bonjour, ceci est un message en français!"
        }
        ["translator_comments"]=>
        string(0) ""
        ["extracted_comments"]=>
        string(0) ""
        ["references"]=>
        array(0) {
        }
        ["flags"]=>
        array(0) {
        }
      }
    }
    

    Hopefully you will have more entries.

    With this output you will be able to undestand what is happening:

    1. The output is an empty Array? Your file is not being loaded or there is a typo in textdomain string.
      • Check textdomain.
      • Check file name.
    2. The output is full of translations? Maybe this translation is missing your strings, or you are not using this translation.
      • Check textdomain in your code, inside any __(), _e(), or any other translation, you may have a typo there.
      • Check strings, they must be identical to translation keys, spaces counts and it’s case sensitive.
    3. After cheching 1 and 2 still no success: you could have some cache in place.
      • Remove any cache plugin.
      • Purge cache if possible.

    Please keep me posted with results.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search