WordPress 插件的国际化:__() 与 load_plugin_textdomain 的正确顺序

· wordpress · 阅读 10
摘要

做了 i18n 却发现翻译不生效,八成是加载时机写错了。标准的三步// 1. 所有字符串用翻译函数包裹 __('Hello', 'my-plugin'); _e('Settings', 'my-plugin'); // 2. 在 plug

做了 i18n 却发现翻译不生效,八成是加载时机写错了。

标准的三步

// 1. 所有字符串用翻译函数包裹
__('Hello', 'my-plugin');
_e('Settings', 'my-plugin');

// 2. 在 plugins_loaded 之后加载语言包
add_action('init', function(){
    load_plugin_textdomain(
        'my-plugin',
        false,
        dirname(plugin_basename(__FILE__)) . '/languages/'
    );
});

为什么不能更早

load_plugin_textdomain() 内部依赖 WP 的语言环境,这个环境在 init 之前还没定下来。挂到 plugins_loaded 上通常也可以,但 init 最稳。

文件名要严格对齐

Domain: my-plugin 对应语言包文件名必须是 my-plugin-zh_CN.mo。大小写和连字符错一个字符都加载不到,而且不会报错,表现为直接显示英文原文。

带变量的字符串

sprintf(__('Deleted %d items', 'my-plugin'), $count);

不要用字符串拼接,语序在不同语言里不一样,必须用占位符。

复数形式

_n('%d comment', '%d comments', $count, 'my-plugin');

中文虽然只有一个形式,但格式还是要按规定写两个参数,否则 .po 文件解析会出错。

调试技巧

怀疑翻译没加载,临时输出 get_locale() 和 is_textdomain_loaded('my-plugin'),两个都对了就是 .mo 文件本身的问题。