Make WordPress Core

Opened 11 years ago

Last modified 7 weeks ago

#23794 assigned enhancement

load_plugin_textdomain fails if plugin is loaded from mu-plugins

Reported by: ideag's profile ideag Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 3.5.1
Component: I18N Keywords: has-patch close
Focuses: Cc:


load_plugin_textdomain is realative to WP_PLUGIN_DIR, so it fails to load localization files if plugin keeps them in its directory.

The function should check if is called from mu-plugins and use WP_MUPLUGIN_DIR in that case.

I can fix this in my own plugin by adding '../mu-lugins/' like this:

  load_plugin_textdomain( 'tiny_tribuna', false, '../mu-plugins/'.dirname( plugin_basename( __FILE__ ) ) . '/languages/');

but this is not a good option for other plugins.

Attachments (2)

23794.patch (1.6 KB) - added by johnbillion 11 years ago.
23794.diff (3.6 KB) - added by swissspidy 8 years ago.

Download all attachments as: .zip

Change History (21)

#1 @ocean90
11 years ago

  • Keywords close added

You should use load_muplugin_textdomain() then.

#2 @ideag
11 years ago

  • Resolution set to fixed
  • Status changed from new to closed

Problem is, a lot of plugins only use load_plugin_textdomain() :| That means I would have to modify them after every upgrade. Oh well, I guess I can contact the creators of those plugins,

#3 @ocean90
11 years ago

  • Keywords close removed
  • Milestone Awaiting Review deleted
  • Resolution changed from fixed to worksforme

#4 @SergeyBiryukov
11 years ago

Here's a workaround I wrote for one of my plugins in case someone decided to put it in mu-plugins:

if ( false !== strpos( __FILE__, basename( WPMU_PLUGIN_DIR ) ) )
	load_muplugin_textdomain( '...' );
	load_plugin_textdomain( '...', false, dirname( plugin_basename( __FILE__ ) ) );

#5 follow-up: @nacin
11 years ago

  • Milestone set to Future Release
  • Resolution worksforme deleted
  • Status changed from closed to reopened
  • Type changed from defect (bug) to enhancement

We should probably merge these functions to look in both directories — plugins then mu-plugins.

#6 in reply to: ↑ 5 @ideag
11 years ago

Replying to nacin:

We should probably merge these functions to look in both directories — plugins then mu-plugins.

something like this?

function load_plugin_textdomain( $domain, $abs_rel_path = false, $plugin_rel_path = false ) {
          $locale = apply_filters( 'plugin_locale', get_locale(), $domain );
	        if ( false !== $plugin_rel_path ) {
	                $path = WP_PLUGIN_DIR . '/' . trim( $plugin_rel_path, '/' );
	        } else if ( false !== $abs_rel_path ) {
	                _deprecated_argument( __FUNCTION__, '2.7' );
	                $path = ABSPATH . trim( $abs_rel_path, '/' );
	        } else {
	                $path = WP_PLUGIN_DIR;

                if (!is_readable($path)) {
                        $path = WPMU_PLUGIN_DIR . '/' . trim( $plugin_rel_path, '/' );
	        $mofile = $path . '/'. $domain . '-' . $locale . '.mo';
	        return load_textdomain( $domain, $mofile );

11 years ago

#7 @johnbillion
11 years ago

23794.patch adds the mu-plugin fallback from ideag and updates the inline docs and deprecated argument so it's in line with other deprecated arguments.

#8 @TroyDesign
11 years ago

I solved using code below:

add_filter( 'load_textdomain_mofile', 'tdc_mu_load_textdomain_mofile', 10, 2 );
function tdc_mu_load_textdomain_mofile($mofile, $domain) {
	$mumofile = WPMU_PLUGIN_DIR.preg_replace('%^'.WP_PLUGIN_DIR.'%','',$mofile);
	if (file_exists($mumofile)) return $mumofile;
	else return $mofile;


add_filter( 'load_textdomain_mofile', 'tdc_mu_load_textdomain_mofile', 10, 2 );
function tdc_mu_load_textdomain_mofile($mofile, $domain) {
	if (preg_match('%^'.WP_PLUGIN_DIR.'(.+)%',$mofile,$m) && file_exists(WPMU_PLUGIN_DIR.$m[1])) return WPMU_PLUGIN_DIR.$m[1];
	else return $mofile;
Last edited 11 years ago by TroyDesign (previous) (diff)

#9 @janw.oostendorp
11 years ago

  • Cc janw.oostendorp@… added

#10 @chriscct7
9 years ago

  • Keywords needs-patch added
  • Severity changed from minor to normal

#11 @danielbachhuber
9 years ago

This is also a problem for plugins installed in themes.

#12 @swissspidy
8 years ago

  • Milestone changed from Future Release to 4.6
  • Owner set to swissspidy
  • Status changed from reopened to assigned

We could tackle this together with #34114 (Remove the requirement to call load_plugin_textdomain() or load_theme_textdomain()), though it might also make this enhancement obsolete. Anyway, it's not a big task.

8 years ago

#13 @swissspidy
8 years ago

  • Keywords has-patch added; needs-patch removed

23794.diff deprecates load_muplugin_textdomain() as per Nacin's comment and makes load_plugin_textdomain() try the mu-plugins directory as well.

@ocean90 Since we worked on #34114, what do you think about this change here?

This ticket was mentioned in Slack in #core by chriscct7. View the logs.

8 years ago

#15 @flixos90
8 years ago

I'm not sure if we should deprecate load_muplugin_textdomain(). I'm curious how many plugin authors do something like the check in Also, shouldn't it be the plugin author's responsibility to support his/her plugin as an mu-plugin as well?

Anyway, if we don't change this, I think we should improve the codex on this - make new plugin authors aware that there is the concept of mu-plugins and how they can support it.

This ticket was mentioned in Slack in #core by voldemortensen. View the logs.

8 years ago

#17 @voldemortensen
8 years ago

  • Milestone changed from 4.6 to Future Release

Punting from 4.6. Please move back if a decision is reached an patch produced.

#18 @swissspidy
8 years ago

  • Owner swissspidy deleted

#19 @swissspidy
7 weeks ago

  • Keywords close added
  • Milestone set to Awaiting Review

Suggesting wontfix since we have just-in-time translation loading

Note: See TracTickets for help on using tickets.