Make WordPress Core

Opened 4 weeks ago

Last modified 4 weeks ago

#64249 new defect (bug)

Automatic translation (JIT) loading doesn't work for network-activated plugins in multisite

Reported by: pelentak's profile pelentak Owned by:
Milestone: 7.0 Priority: normal
Severity: normal Version: 6.7
Component: I18N Keywords: needs-patch
Focuses: multisite Cc:

Description

Description

The automatic just-in-time (JIT) translation loading introduced in [59461] for WordPress 6.7+ only registers text domains for site-level active plugins, but completely skips network-activated plugins in multisite environments.

This causes PHP translations (via __(), _e(), etc.) to fail for network-activated plugins, even when the plugin has correct Text Domain and Domain Path headers and translation files are present. Interestingly, JavaScript translations (.json files) continue to work correctly.

Possible Root Cause

In wp-settings.php, the automatic translation registration code processes plugins from wp_get_active_and_valid_plugins() but does not process plugins from wp_get_active_network_plugins().

The relevant code added in [59461] around line 380-390 of wp-settings.php:

<?php
// Register plugin translations for active plugins
foreach ( wp_get_active_and_valid_plugins() as $plugin ) {
    $plugin_data = get_plugin_data( $plugin, false, false );
    
    if ( ! empty( $plugin_data['TextDomain'] ) && ! empty( $plugin_data['DomainPath'] ) ) {
        // Translation registration happens here
    }
}

However, there is no equivalent loop for network-activated plugins loaded earlier via wp_get_active_network_plugins().

Steps to Reproduce

Set up a WordPress Multisite installation (any configuration: subdirectory or subdomain)
Create or install a plugin with:

Proper plugin headers including Text Domain: my-plugin and Domain Path: /languages
Translation files in the plugin's /languages directory (e.g., my-plugin-de_DE.mo)
PHP code using translation functions like __('Text', 'my-plugin')

Network Activate the plugin
Set the site language to match the translation file (e.g., German de_DE)
View the plugin's output on the front-end or admin

Expected Behavior

The plugin's translations should load automatically without requiring load_plugin_textdomain(), just as they do for site-level activated plugins. The plugin should display translated text in German.

Actual Behavior

The plugin displays English text (the original untranslated strings) because the text domain was never registered during the WordPress bootstrap process. Network-activated plugins must explicitly call load_plugin_textdomain() as a workaround.

Change History (1)

#1 @swissspidy
4 weeks ago

  • Milestone changed from Awaiting Review to 7.0
  • Version changed from trunk to 6.7
Note: See TracTickets for help on using tickets.