Function in a plugin is behaving differently than function in the functions.php inside a child theme.

I have a custom simple plain plugin with nothing but the following code in it and it works perfectly. It translates wpamelia plugin correctly with all strings as expected.

add_filter( 'load_textdomain_mofile', 'load_custom_plugin_translation_file', 2, 2 );
function load_custom_plugin_translation_file( $mofile, $domain ) {
  if ( 'wpamelia' === $domain ) {
    $mofile = ABSPATH . DIRECTORY_SEPARATOR . 'wp-content' . DIRECTORY_SEPARATOR . 'plugins' . '/amelia-translate/de_DE/wpamelia-de_DE.mo';
  return $mofile;

When I put the same code into my child theme's functions.php file and disable the custom plugin with code above, translation stops showing.

When I output all $mofile variables from the load_textdomain_mofile filter into error_log for debugging purposes, all but 'wpamelia' textdomain are present. So I tried translating another plugin this way, to make sure it is plugin related issue, again it worked from the plugin file, but not from functions.php.

The .mo file path is tested and valid, file exists.

I tried using different function name instead of load_custom_plugin_translation_file so there is no conflict with the disabled plugin.

Why is the same function behaving differently when part of a plugin and differently when in functions.php? Is child theme not meant to be used with load_textdomain_mofile?


In the original plugin WPAmelia's code, translation is loaded this way:

load_plugin_textdomain('wpamelia', false, plugin_basename(__DIR__) . '/languages/' . AMELIA_LOCALE . '/');

So I put following line into the after_setup_theme function and and moved the .mo file into this directory, it started partialy working.

load_textdomain( 'wpamelia', get_stylesheet_directory() . '/translations/wpamelia/wpamelia-de_DE.mo' );

Everything is translated fine, front end, back end, but the wp admin menu in back-end is not.

Back-end admin menu is quite important for using this plugin correctly. I tried to play with after_setup_theme's priority, (0 - 999) but it did not help at all.

1 Answer 1


If you load a text domain in child theme, you may need call it in after_setup_theme filter which loads immediately after all the theme functions.php. You may refer to this note

It could be due to the loading sequence. Since I haven't seen it in your above code. I guess you load the text domain in some other hooks or no hook which is later than the loading of load_textdomain function. I have tried also load the text domain without hook. It seems it still not up to the point of loading.

I have just setup a test and read the source code to reproduce same result as you. You may try the following: (putting your child theme domain to load inside this action). And then place the following in your child theme function.php

// for translating a theme
add_action( 'after_setup_theme', 'ws365011_child_theme_setup' );
function ws365011_child_theme_setup() {
    load_child_theme_textdomain('wpamelia', get_stylesheet_directory() .'/languages'); // frontend

About load_child_theme_textdomain, according to source code, it is just a shortcut of load_theme_textdomain with path checking for child theme, while load_theme_textdomain is a wrapper of load_textdomain with checking of mo file and and path.

If it is not working in load_child_theme_textdomain, it could be the override or checking parts not working. Because there are filters for override in load_theme_textdomain and load_textdomain. You may examine it in your case after everything is working as an experiment and experience for future development.

Update: For plugin, you may need to put into a plugins_loaded to have to correct timing.

So your code might look like this, assumed that your file exist.

// for translating a plugin
add_action( 'plugins_loaded', 'ws365030_load_plugin_textdomain' );
function ws365030_load_plugin_textdomain() {
    load_plugin_textdomain('wpamelia', false, plugin_basename(__DIR__) . '/languages/' . AMELIA_LOCALE . '/');

Hope it helps.

  • Tank you, I tried the after_setup_theme, but load_child_theme_textdomain does not seem to work. I looked into the plugin's code, made some changes, now it works partially - can't figure out how to translate back-end admin menu. I updated my question.
    – Mike
    Commented Apr 25, 2020 at 19:00
  • 1
    @Mike I have added the hook that you need for loading text domain for a plugin. Please try to see and help it works for you. Commented Apr 27, 2020 at 7:39
  • Thank you @simongcc, plugins loaded did not work either, thank you for your help, I will try some other solutions.
    – Mike
    Commented Apr 27, 2020 at 9:55
  • @Mike no worries, maybe you could download some big plugins to see how they handle it and then use a simplified prototype to test up a solutions for yourself. Commented Apr 27, 2020 at 12:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.