Make WordPress Core


Ignore:
Timestamp:
10/02/2024 01:42:11 PM (2 months ago)
Author:
swissspidy
Message:

I18N: Do not load translations directly in load_*_textdomain.

In [59127], _doing_it_wrong warnings were added if plugins or themes load translations too early, either through a manual function call or just-in-time loading.

Because many plugins and themes still manually call load_plugin_textdomain(), load_theme_textdomain() or load_muplugin_textdomain(), even though they don't have to anymore, that caused a lot of warnings.

With this new approach, these functions merely register the translations path in the existing WP_Textdomain_Registry and do not immediately try to load the translations anymore. The loading is all handled by the just-in-time functionality.

This way, warnings will only be emitted if triggering the just-in-time loading too early, greatly improving the developer experience and to a degree also performance.

Props swissspidy, sergeybiryukov, mukesh27.
See #44937.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/l10n.php

    r59127 r59157  
    984984 * @since 1.5.0
    985985 * @since 4.6.0 The function now tries to load the .mo file from the languages directory first.
     986 * @since 6.7.0 Translations are no longer immediately loaded, but handed off to the just-in-time loading mechanism.
    986987 *
    987988 * @param string       $domain          Unique identifier for retrieving translated strings
     
    998999    if ( ! is_string( $domain ) ) {
    9991000        return false;
    1000     }
    1001 
    1002     if ( ! doing_action( 'after_setup_theme' ) && ! did_action( 'after_setup_theme' ) ) {
    1003         _doing_it_wrong(
    1004             __FUNCTION__,
    1005             sprintf(
    1006                 /* translators: 1: The text domain. 2: 'after_setup_theme'. */
    1007                 __( 'Attempted to load translations for the %1$s domain too early. Translations should be loaded after the %2$s action has fired, to ensure that the current user is already set up.' ),
    1008                 '<code>' . $domain . '</code>',
    1009                 '<code>after_setup_theme</code>'
    1010             ),
    1011             '6.7.0'
    1012         );
    1013     }
    1014 
    1015     /**
    1016      * Filters a plugin's locale.
    1017      *
    1018      * @since 3.0.0
    1019      *
    1020      * @param string $locale The plugin's current locale.
    1021      * @param string $domain Text domain. Unique identifier for retrieving translated strings.
    1022      */
    1023     $locale = apply_filters( 'plugin_locale', determine_locale(), $domain );
    1024 
    1025     $mofile = $domain . '-' . $locale . '.mo';
    1026 
    1027     // Try to load from the languages directory first.
    1028     if ( load_textdomain( $domain, WP_LANG_DIR . '/plugins/' . $mofile, $locale ) ) {
    1029         return true;
    10301001    }
    10311002
     
    10411012    $wp_textdomain_registry->set_custom_path( $domain, $path );
    10421013
    1043     return load_textdomain( $domain, $path . '/' . $mofile, $locale );
     1014    return true;
    10441015}
    10451016
     
    10491020 * @since 3.0.0
    10501021 * @since 4.6.0 The function now tries to load the .mo file from the languages directory first.
     1022 * @since 6.7.0 Translations are no longer immediately loaded, but handed off to the just-in-time loading mechanism.
    10511023 *
    10521024 * @global WP_Textdomain_Registry $wp_textdomain_registry WordPress Textdomain Registry.
     
    10651037    }
    10661038
    1067     if ( ! doing_action( 'after_setup_theme' ) && ! did_action( 'after_setup_theme' ) ) {
    1068         _doing_it_wrong(
    1069             __FUNCTION__,
    1070             sprintf(
    1071                 /* translators: 1: The text domain. 2: 'after_setup_theme'. */
    1072                 __( 'Attempted to load translations for the %1$s domain too early. Translations should be loaded after the %2$s action has fired, to ensure that the current user is already set up.' ),
    1073                 '<code>' . $domain . '</code>',
    1074                 '<code>after_setup_theme</code>'
    1075             ),
    1076             '6.7.0'
    1077         );
    1078     }
    1079 
    1080     /** This filter is documented in wp-includes/l10n.php */
    1081     $locale = apply_filters( 'plugin_locale', determine_locale(), $domain );
    1082 
    1083     $mofile = $domain . '-' . $locale . '.mo';
    1084 
    1085     // Try to load from the languages directory first.
    1086     if ( load_textdomain( $domain, WP_LANG_DIR . '/plugins/' . $mofile, $locale ) ) {
    1087         return true;
    1088     }
    1089 
    10901039    $path = WPMU_PLUGIN_DIR . '/' . ltrim( $mu_plugin_rel_path, '/' );
    10911040
    10921041    $wp_textdomain_registry->set_custom_path( $domain, $path );
    10931042
    1094     return load_textdomain( $domain, $path . '/' . $mofile, $locale );
     1043    return true;
    10951044}
    10961045
     
    11051054 * @since 1.5.0
    11061055 * @since 4.6.0 The function now tries to load the .mo file from the languages directory first.
     1056 * @since 6.7.0 Translations are no longer immediately loaded, but handed off to the just-in-time loading mechanism.
    11071057 *
    11081058 * @global WP_Textdomain_Registry $wp_textdomain_registry WordPress Textdomain Registry.
     
    11211071    }
    11221072
    1123     if ( ! doing_action( 'after_setup_theme' ) && ! did_action( 'after_setup_theme' ) ) {
    1124         _doing_it_wrong(
    1125             __FUNCTION__,
    1126             sprintf(
    1127                 /* translators: 1: The text domain. 2: 'after_setup_theme'. */
    1128                 __( 'Attempted to load translations for the %1$s domain too early. Translations should be loaded after the %2$s action has fired, to ensure that the current user is already set up.' ),
    1129                 '<code>' . $domain . '</code>',
    1130                 '<code>after_setup_theme</code>'
    1131             ),
    1132             '6.7.0'
    1133         );
    1134     }
    1135 
    1136     /**
    1137      * Filters a theme's locale.
    1138      *
    1139      * @since 3.0.0
    1140      *
    1141      * @param string $locale The theme's current locale.
    1142      * @param string $domain Text domain. Unique identifier for retrieving translated strings.
    1143      */
    1144     $locale = apply_filters( 'theme_locale', determine_locale(), $domain );
    1145 
    1146     $mofile = $domain . '-' . $locale . '.mo';
    1147 
    1148     // Try to load from the languages directory first.
    1149     if ( load_textdomain( $domain, WP_LANG_DIR . '/themes/' . $mofile, $locale ) ) {
    1150         return true;
    1151     }
    1152 
    11531073    if ( ! $path ) {
    11541074        $path = get_template_directory();
     
    11571077    $wp_textdomain_registry->set_custom_path( $domain, $path );
    11581078
    1159     return load_textdomain( $domain, $path . '/' . $locale . '.mo', $locale );
     1079    return true;
    11601080}
    11611081
     
    14261346            __FUNCTION__,
    14271347            sprintf(
    1428                 /* translators: %s: The text domain. */
    1429                 __( 'Translation loading for the %s domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early.' ),
    1430                 '<code>' . $domain . '</code>'
     1348                /* translators: 1: The text domain. 2: 'init'. */
     1349                __( 'Translation loading for the %1$s domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the %2$s action or later.' ),
     1350                '<code>' . $domain . '</code>',
     1351                '<code>init</code>'
    14311352            ),
    14321353            '6.7.0'
Note: See TracChangeset for help on using the changeset viewer.