load_plugin_textdomain()
云策文档标注
概述
load_plugin_textdomain() 函数用于加载插件的翻译字符串(.mo 文件),支持自定义路径和文本域。自 WordPress 6.7.0 起,翻译采用即时加载机制,建议在 init 钩子中调用以避免过早加载问题。
关键要点
- 函数参数:$domain(必需,文本域标识符)、$deprecated(已弃用,替代为 $plugin_rel_path)、$plugin_rel_path(可选,.mo 文件相对路径)。
- 返回布尔值:成功加载返回 true,否则返回 false。
- 路径处理:若未指定 $plugin_rel_path,默认使用 WP_PLUGIN_DIR 根目录。
- 即时加载机制:WordPress 6.7.0 引入,翻译不再立即加载,而是延迟到需要时。
- 钩子使用:推荐在 init 钩子中调用 load_plugin_textdomain(),避免使用 plugins_loaded 钩子(可能导致过早加载警告)。
- 文本域命名:应使用短横线、小写字母且无空格(例如 'wpdocs-textdomain')。
- 自动加载:对于 WordPress.org 托管插件,自 4.6 版起可从标准语言目录自动加载翻译,6.7 版后手动调用可能不再必要。
代码示例
add_action( 'init', 'wpdocs_load_textdomain' );
function wpdocs_load_textdomain() {
load_plugin_textdomain( 'wpdocs-textdomain', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
}注意事项
- 避免在 plugins_loaded 钩子中调用,否则可能触发过早加载警告(如 WordPress 6.7.0 的 PHP 通知)。
- 使用 init 钩子时,可设置优先级为 0 以确保在 widgets_init 等操作前加载翻译。
- 函数内部处理弃用参数并调用 _deprecated_argument() 进行提示。
- 翻译文件命名应基于文本域和区域设置(例如 textdomain-zh_CN.mo)。
原文内容
Loads a plugin’s translated strings.
Description
If the path is not given then it will be the root of the plugin directory.
The .mo file should be named based on the text domain with a dash, and then the locale exactly.
Parameters
$domainstringrequired-
Unique identifier for retrieving translated strings
$deprecatedstring|falseoptional-
Deprecated. Use the $plugin_rel_path parameter instead.
Default:
false $plugin_rel_pathstring|falseoptional-
Relative path to WP_PLUGIN_DIR where the .mo file resides.
Default:
false
Source
function load_plugin_textdomain( $domain, $deprecated = false, $plugin_rel_path = false ) {
/** @var WP_Textdomain_Registry $wp_textdomain_registry */
/** @var array<string, WP_Translations|NOOP_Translations> $l10n */
global $wp_textdomain_registry, $l10n;
if ( ! is_string( $domain ) ) {
return false;
}
if ( false !== $plugin_rel_path ) {
$path = WP_PLUGIN_DIR . '/' . trim( $plugin_rel_path, '/' );
} elseif ( false !== $deprecated ) {
_deprecated_argument( __FUNCTION__, '2.7.0' );
$path = ABSPATH . trim( $deprecated, '/' );
} else {
$path = WP_PLUGIN_DIR;
}
$wp_textdomain_registry->set_custom_path( $domain, $path );
// If just-in-time loading was triggered before, reset the entry so it can be tried again.
if ( isset( $l10n[ $domain ] ) && $l10n[ $domain ] instanceof NOOP_Translations ) {
unset( $l10n[ $domain ] );
}
return true;
}
Skip to note 9 content
Fahad Alduraibi
Loading the plugin translations should not be done during
plugins_loadedaction since that is too early and prevent other language related plugins from correctly hooking up withload_textdomain()function and doing whatever they want to do.Calling
load_plugin_textdomain()should be delayed untilinitaction.add_action( 'init', 'wpdocs_load_textdomain' ); /** * Load plugin textdomain. */ function wpdocs_load_textdomain() { load_plugin_textdomain( 'wpdocs_textdomain', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' ); }after_setup_themecan work better. The default WordPress themes use this hook to load the theme textdomains and some plugininitactions require the translations to be in place and load before the default priority 10.inithook doesn’t work for all the strings. For example, translations for admin menu items will not be loaded, while later strings will be translated.plugins_loadedhook is more appropriate than theinithook for loading translations because it ensures that all plugins are fully loaded before your plugin’s text domain is registered.Skip to note 10 content
Pablo Pacheco
Just a note,
<strong>load_plugin_textdomain()</strong>will try to load the mo file firstly from:WP_LANG_DIR . ‘/plugins/’ . $mofile
Only if it is not able to it will load it from WP_PLUGIN_DIR folder
Skip to note 11 content
Gabriel Reguly
“The text domain name must use dashes and not underscores, be lower case, and have no spaces.”
Source: https://developer.wordpress.org/plugins/internationalization/how-to-internationalize-your-plugin/
So use ‘wpdocs-textdomain’ instead of ‘wpdocs_textdomain’, e.g.
<br />
load_plugin_textdomain( 'wpdocs-textdomain', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );<br />
Skip to note 12 content
coderalamin
load_plugin_textdomain() is no longer necessary for plugins hosted on WordPress.org. Since WordPress 4.6, translations are automatically loaded from the languages directory, and since 6.7, a just-in-time loading system is used. Calling this function manually is now discouraged. It’s recommended to just use proper text domains in your __() , _e() , and other translation functions, and place .mo files in the standard plugin languages folder.
Skip to note 13 content
Deepak Rajpal
WordPress 6.7.0 has started showing following notice if
load_plugin_textdomainis loaded withplugins_loadedhook.As mentioned in this documentation/notes, use
inithook instead ofplugins_loadedto fix it.Example:
function wpdocs_init() { load_plugin_textdomain( 'wpdocs-textdomain', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' ); } add_action( 'plugins_loaded', 'wpdocs_init' );Skip to note 14 content
Mark Westguard
If you are using the
widgets_inithook in a plugin, I’d suggest setting the priority to 0 when usingadd_actionto run theload_plugin_textdomainfunction. For example:add_action( 'init', 'my_load_plugin_textdomain_function', 0 );The reason for this is that the
widgets_initaction runs as a result of a priority 1inithook. In your extendedWP_Widgetclass you might use l10n functions such as__()to label or describe the widget. This therefore needs to happen afterload_plugin_textdomainis called.Use of
__()prior to using theload_plugin_textdomainfunction will result in subsequent translations failing for that registered domain.Skip to note 15 content
Binsaifullah
Plugin Text domain load
function my_plugin_init() { load_plugin_textdomain( 'my-textdomain', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' ); } add_action( 'plugins_loaded', 'my_plugin_init' );initaction (and notplugins_loaded).Skip to note 16 content
FARAZFRANK
<br />
/**<br />
* Load plugin textdomain.<br />
*/<br />
function load_translation() {<br />
load_plugin_textdomain( 'your-plugin-textdomain', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );<br />
}<br />
add_action( 'plugins_loaded', 'load_translation' );<br />
The
plugins_loadedhook is more appropriate than theinithook for loading translations because it ensures that all plugins are fully loaded before your plugin’s text domain is registered. This avoids potential issues with translation files being loaded too early.plugins_loadedhook: This hook fires after all active plugins have been loaded. It’s the recommended place for loading the text domain since all necessary plugin files will be available by then.inithook: While it can work, it’s fired earlier than plugins_loaded, and loading the text domain here may result in translations not being fully registered, especially if your plugin depends on other plugins being loaded.Therefore, using plugins_loaded is the best practice for ensuring reliable translation loading.
plugins_loadedis beforeinitand is too early for loading translations.inithook is running after theplugins_loadedhook! With WordPress 6.7, it is recommended to useinithook, asplugins_loadedwill give an error: “PHP Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for theexample-textdomaindomain 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 theinitaction or later.”plugins_loadedinstead ofinitwill now give you a warning. Don’t use it!