详解 WordPress `_e()` 函数的源码:如何直接输出翻译后的字符串。

各位同学,大家好!今天咱们来聊聊 WordPress 里一个非常实用,但又容易被忽视的小家伙:_e() 函数。别看它名字短小精悍,作用可不小,它可是实现 WordPress 多语言支持的关键一环。

开场白:翻译官的自我修养

想象一下,你是一个翻译官,老板(WordPress)给你一句话(一段字符串),让你翻译成指定语言,然后大声地喊出来,让大家都听到。_e() 函数就扮演着这个翻译官的角色,它负责翻译字符串,并且直接把它打印到页面上。

_e() 函数:闪亮登场

_e() 函数的定义非常简单,位于 wp-includes/l10n.php 文件中。让我们先来看看它的庐山真面目:

function _e( $text, $domain = 'default' ) {
    echo translate( $text, $domain );
}

是不是很简单? 它的作用就是调用 translate() 函数对 $text 进行翻译,然后使用 echo 语句直接输出翻译后的结果。

拆解 _e():一步一步看清楚

咱们来一步一步分析,看看 _e() 函数是如何完成翻译并输出的:

  1. 参数接收:

    • $text:这是要翻译的字符串。可以是任何你想展示给用户的文本,比如 "Hello World!"、"欢迎来到我的博客!" 等。
    • $domain:这是一个可选参数,用于指定文本的翻译域(text domain)。翻译域就像是一个分类标签,告诉 WordPress 应该从哪个翻译文件(.mo 文件)中查找对应的翻译。 默认值为 'default',表示使用默认的翻译域。
  2. 调用 translate()

    • translate( $text, $domain ):这是核心的翻译函数。它接收要翻译的文本 $text 和翻译域 $domain 作为参数,然后返回翻译后的字符串。
  3. echo 输出:

    • echo translate( $text, $domain );echo 语句将 translate() 函数返回的翻译后的字符串直接输出到 HTML 页面中。

translate() 函数:翻译的核心引擎

既然 _e() 函数的核心在于 translate() 函数,那我们就必须深入了解一下 translate() 函数的工作原理。translate() 函数的代码比较复杂,我们不会逐行分析,但会抓住关键点:

function translate( $text, $domain = 'default' ) {
    global $l10n;

    $text = (string) $text;

    if ( isset( $l10n[ $domain ] ) ) {
        return $l10n[ $domain ]->translate( $text );
    }

    return $text;
}
  • global $l10n;: 声明全局变量 $l10n。 这个变量是一个数组,存储了所有已加载的翻译对象。 每个翻译对象对应一个翻译域。
  • 类型转换: $text = (string) $text;: 确保 $text 是字符串类型。
  • 检查翻译域是否存在: isset( $l10n[ $domain ] ): 检查指定的翻译域 $domain 是否已经加载到 $l10n 数组中。 如果存在,说明已经加载了相应的翻译文件。
  • 执行翻译: $l10n[ $domain ]->translate( $text ): 如果翻译域存在,则调用对应翻译对象的 translate() 方法来执行实际的翻译操作。 这个 translate() 方法是 gettext 类的成员方法。
  • 未找到翻译: return $text;: 如果指定的翻译域不存在,或者在翻译文件中找不到对应的翻译,则 translate() 函数直接返回原始的 $text,不做任何修改。

$l10n 全局变量:翻译数据的大本营

$l10n 是一个全局数组,它存储了所有已加载的翻译数据。 它的结构大致如下:

$l10n = array(
    'default' => object(gettext), // 默认翻译域
    'my-theme' => object(gettext), // 自定义主题的翻译域
    'my-plugin' => object(gettext), // 自定义插件的翻译域
    // ... 更多翻译域
);

每个翻译域对应一个 gettext 类的对象。 gettext 类负责加载和管理 .mo 翻译文件,并提供翻译功能。

翻译流程:从文本到输出

现在,让我们用一个表格来总结 _e() 函数的整个翻译流程:

步骤 描述 涉及的函数/变量
1 调用 _e() 函数,传入要翻译的文本 $text 和翻译域 $domain(可选)。 _e()
2 _e() 函数调用 translate() 函数,将 $text$domain 传递给它。 translate()
3 translate() 函数检查 $l10n 全局数组中是否存在指定的翻译域 $domain $l10n
4 如果存在翻译域,则调用对应 gettext 对象的 translate() 方法,查找 $text 的翻译。 gettext->translate()
5 gettext->translate() 方法在 .mo 翻译文件中查找 $text 的翻译。 .mo 文件
6 如果找到翻译,则返回翻译后的字符串;否则,返回原始的 $text
7 translate() 函数将翻译后的字符串返回给 _e() 函数。
8 _e() 函数使用 echo 语句将翻译后的字符串直接输出到 HTML 页面中。 echo

使用 _e():实例演示

光说不练假把式,让我们通过几个实例来看看 _e() 函数的具体用法:

  • 基本用法:
<?php _e( 'Hello World!', 'my-theme' ); ?>

这段代码会将 "Hello World!" 翻译成当前站点的语言,并直接输出到页面上。 my-theme 是翻译域, 告诉 WordPress 从 my-theme 对应的 .mo 文件中查找翻译。

  • 在 HTML 属性中使用:
<button><?php _e( 'Click Here', 'my-plugin' ); ?></button>

这段代码会将 "Click Here" 翻译后作为按钮的文本显示。

  • 结合变量使用:
<?php
$username = '张三';
$message = sprintf( __( 'Welcome, %s!', 'my-theme' ), $username );
_e( $message );
?>

这里使用了 sprintf() 函数和 __() 函数(我们稍后会讲到)来创建一个包含变量的翻译字符串,然后使用 _e() 函数输出。

__() 函数:_e() 的好兄弟

你可能注意到了上面的例子中出现了 __() 函数。 __() 函数和 _e() 函数非常相似, 唯一的区别是 __() 函数只是返回翻译后的字符串,而 _e() 函数会直接输出翻译后的字符串。

function __( $text, $domain = 'default' ) {
    return translate( $text, $domain );
}

你可以根据需要选择使用 _e()__() 函数。 如果你需要将翻译后的字符串赋值给一个变量,或者在 HTML 属性中使用,那么应该使用 __() 函数。 如果你只需要直接输出翻译后的字符串,那么可以使用 _e() 函数。

翻译域的重要性:避免命名冲突

翻译域的作用是避免不同主题或插件之间的翻译字符串发生冲突。 想象一下,如果你的主题和插件都使用了相同的翻译字符串 "Hello",但是你希望它们显示不同的翻译, 那么就需要使用不同的翻译域来区分它们。

通常,我们建议使用主题或插件的名称作为翻译域。 例如,你的主题名为 "My Theme",那么你可以使用 "my-theme" 作为翻译域。 你的插件名为 "My Plugin",那么可以使用 "my-plugin" 作为翻译域。

创建和使用 .mo 翻译文件

要使 _e()__() 函数能够正常工作, 你需要创建和使用 .mo 翻译文件。 .mo 文件包含了所有翻译字符串的对应关系。

创建 .mo 文件的步骤如下:

  1. 创建 .po 文件: .po 文件是纯文本文件,包含了原始字符串和对应的翻译。 你可以使用 Poedit 等工具来创建 .po 文件。
  2. 使用 xgettext 命令提取字符串: xgettext 命令可以扫描你的 PHP 代码,自动提取所有使用了 _e()__() 函数的字符串,并将它们添加到 .po 文件中。
  3. 编辑 .po 文件,添加翻译: 打开 .po 文件, 为每个原始字符串添加对应的翻译。
  4. 将 .po 文件编译成 .mo 文件: 使用 Poedit 等工具将 .po 文件编译成 .mo 文件。

将 .mo 文件放置到正确的位置:

  • 主题: 将 .mo 文件放置到主题的 languages 目录下。 例如,你的主题名为 "My Theme",那么 .mo 文件应该放置在 wp-content/themes/my-theme/languages/ 目录下。
  • 插件: 将 .mo 文件放置到插件的 languages 目录下。 例如,你的插件名为 "My Plugin",那么 .mo 文件应该放置在 wp-content/plugins/my-plugin/languages/ 目录下。

加载翻译文件:告诉 WordPress 去哪里找翻译

仅仅将 .mo 文件放置到正确的位置是不够的, 你还需要告诉 WordPress 去哪里加载这些翻译文件。

  • 主题: 在主题的 functions.php 文件中添加以下代码:
function my_theme_load_textdomain() {
    load_theme_textdomain( 'my-theme', get_template_directory() . '/languages' );
}
add_action( 'after_setup_theme', 'my_theme_load_textdomain' );
  • 插件: 在插件的主文件中添加以下代码:
function my_plugin_load_textdomain() {
    load_plugin_textdomain( 'my-plugin', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
}
add_action( 'plugins_loaded', 'my_plugin_load_textdomain' );

这些代码会在 WordPress 初始化时加载指定的翻译文件。

总结:翻译的艺术

_e() 函数是 WordPress 多语言支持的基础。 通过它,我们可以轻松地将网站内容翻译成不同的语言,从而吸引更多的用户。 掌握 _e() 函数的用法, 你就掌握了 WordPress 翻译的艺术。

练习题:

  1. 创建一个新的 WordPress 插件,并在插件中使用 _e() 函数输出一段文本。
  2. 为插件创建一个 .mo 翻译文件,并将文本翻译成中文。
  3. 加载翻译文件,并验证插件是否能够正确显示中文翻译。

希望今天的讲座对大家有所帮助! 祝大家学习愉快! 下课!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注