WPML

按照我们的分步指南,让您的插件和主题与 WPML 兼容。

本指南面向已加入我们的兼容性计划(Go Global)的主题和插件作者。如果您尚未加入,请在按照本指南操作之前提交申请。

如何实现 WPML 兼容

1. 创建语言配置文件

语言配置文件会告诉 WPML 您的插件或主题中哪些文本需要翻译(哪些不需要)。这包括自定义文章类型、分类法、字段、管理后台屏幕、小工具等中的文本。

如果您已经知道如何创建语言配置文件,请按照以下说明测试您的设置。否则,请参阅我们的语言配置指南了解如何创建。

测试设置
1. 创建一些文章和分类法
2. 将其发送以进行翻译
3. 验证其在前端是否显示为已翻译

2. 准备要翻译的字符串

字符串是指网站上显示的任何不属于文章、页面或分类法的文本。要让 WPML 翻译您的插件或主题中的字符串,请按照以下针对每种用例的说明进行操作。

在配置字符串时,请使用 Multilingual Tools 插件来验证哪些字符串可翻译,以及哪些需要额外配置。

硬编码字符串

硬编码字符串需要使用 gettext 函数进行注册。了解有关使用 gettext 和准备代码的更多信息。

wp_options 中的字符串

如果您的插件或主题使用 wp_options 表中的字符串,请在 wpml-config.xml 文件中注册它们。

如果您的选项键不固定,并且您的主题使用可能会随着用户输入而增长的条目数组,请动态注册这些条目。您可以使用 WPML 的 API 函数来执行此操作。

动态字符串

如果上述方法均不适用于您的字符串,请按照以下指南准备要翻译的字符串:

测试设置
1. 在 WPML主题和插件本地化中扫描插件/主题中的字符串 
2. 创建一个包含字符串的页面
3. 检查字符串是否出现在字符串翻译中
4. 翻译一些字符串并验证它们在前端是否显示为已翻译

3. 注册要翻译的自定义小工具和区块

如果您的主题或插件包含适用于页面构建器(如 Elementor)的自定义小工具,则需要注册它们以进行翻译。

参阅以下指南了解有关注册页面构建器内容的更多信息:

测试设置
1. 创建一个包含所有自定义小工具的页面
2. 将页面发送以进行翻译,并验证小工具文本是否出现在高级翻译编辑器中
3. 检查翻译是否显示在前端
4. 重复上述步骤以测试不同的小工具设置

4. 自动获取不同语言的 ID

如果您的主题或插件具有在每种语言中加载不同文章 ID 的功能或选项,请使用 wpml_object_id 过滤器自动获取已翻译的文章 ID。

例如,假设一个滑块包含不同语言的幻灯片,每张幻灯片都有唯一的 ID。要自动在每种语言中加载正确的幻灯片 ID,我们可以使用 wpml_object_id 过滤器:

// Loop posts
while (have_posts()): the_post();
$post = get_post( apply_filters( 'wpml_object_id', $post->ID, 'slide' ) );

测试设置
1. 创建相关的文章/模板等,并添加文本字符串
2. 将您的功能设置为使用该文章
3. 翻译文章并在文本字符串中设置不同的值
4. 检查该功能是否在前端加载了已翻译的 ID

5. 实现 WooCommerce 兼容

WPML 可以使用其 WPML Multilingual & Multicurrency for WooCommerce 附加组件翻译 WooCommerce 内容。如果您的主题或插件包含 WooCommerce 元素,请按照我们的 WPML Multilingual & Multicurrency for WooCommerce 兼容性指南使其与 WPML 兼容。

6. 显示或隐藏管理后台语言切换器

默认情况下,WPML 会在 WordPress 管理栏中添加一个语言切换器。登录用户可在前端和后台看到此切换器。

顶部管理栏中的语言切换器
顶部管理栏中的语言切换器

在某些情况下,您可能希望在敏感页面(如设置区域)上隐藏语言切换器。为此,请将以下代码添加到 functions.php 文件中:

//Make sure to rename the function before adding to your plugin
add_filter( 'wpml_show_admin_language_switcher', 'compsupp_disable_wpml_admin_lang_switcher' );
 
function compsupp_disable_wpml_admin_lang_switcher( $state ) {
    global $pagenow;
 
    // Add the admin pages that we need to hide the language switcher
    $admin_pages_to_hide_ls = array(
        'admin-page-slug', 'another-admin-page-slug', 'one-more-admin-page-slug'
    );
 
    // We can also have a filter here in case we need to add/remove pages later
    $admin_pages_to_hide_ls = apply_filters( 'compsupp_filter_disable_wpml_lang_switcher_in_admin', $admin_pages_to_hide_ls);
     
    if (
        $pagenow == 'admin.php'
        && isset( $_GET['page'] )
        && in_array( $_GET['page'], $admin_pages_to_hide_ls)
    ) {
        $state = false;
    }
    return $state;
}

让特殊功能兼容

如果您的主题或插件包含特殊功能(如使用自定义表),则需要使用自定义代码使其与 WPML 兼容。

参阅我们的开发者资源,了解有关自定义开发的信息。

常见问题及解决方案

表单标签无法翻译,因为它们来自数据库

解决方案:

$label = esc_html( apply_filters('wpml_translate_single_string', $this->checkout_item->name, 'wpsc', '$this->checkout_item->name .'_checkout_form_label'' ) );
wp_query($args) 或 get_posts($args) 未过滤出当前语言的正确文章 ID

解决方案:

如果您使用 wp_query($args) 或 get_posts($args),则需要在参数中添加“suppress_filters=0”。

所有幻灯片都以同一种语言显示

解决方案:

// Unset not translated slides
foreach( $slides as $k => $slide ) {
	$check = apply_filters( 'wpml_post_language_details', NULL, $slide->ID )
	$slide_language_code = substr( $check['locale'], 0, 2 );

	if( $check['different_language'] ) {
		unset( $slides[$k] );
	}
}
幻灯片 ID 在第二种语言中不同

解决方案:

// Loop posts
while (have_posts()): the_post();
$post = get_post( apply_filters( 'wpml_object_id', $post->ID, 'slide' ) );
滑块使用自定义管理后台页面,我需要将自定义字段值注册到翻译中

解决方案:

// Adding a new slide code
$slide_id = $this->slide->ID;
$url = $fields['url'];

// Register slide URL to translations
do_action( 'wpml_register_single_string', 'Slider', 'Slide_ID_' . $this->slide->ID, $url);

$this->add_or_update_or_delete_meta($this->slide->ID, 'url', $url);
自定义分类法 ID 在第二种语言中不同

解决方案:

$taxonomy_id = apply_filters( 'wpml_object_id', $taxonomy_id, 'my_custom_taxonomy' );
自定义(非标准 WordPress)AJAX 请求始终返回默认语言内容

解决方案:

在构建自定义 AJAX URL 时,请使用 wpml_current_language 钩子,并将当前语言作为 AJAX URL 的参数添加。

$ajax_url = 'http://my-site.com/wp-content/plugins/my-plugin/handle-ajax.php';
$my_current_lang = apply_filters( 'wpml_current_language', NULL ); 
if ( $my_current_lang ) {
	$ajax_url = add_query_arg( 'wpml_lang', $my_current_lang, $ajax_url );
	// $ajax_url will be something like 'http://my-site.com/wp-content/plugins/my-plugin/handle-ajax.php?wpml_lang=es'
}

在 handle-ajax.php 文件中处理 AJAX 请求时,在生成内容输出之前,请使用 wpml_switch_language 钩子切换内容语言。完成后关闭语言作用域。从 WPML 5.0 开始,语言切换支持嵌套,因此每次切换都需要各自的恢复操作。

if ( ! empty( $_GET[ 'wpml_lang' ] ) ) {
    // Opens a language scope. Only a non-empty language code switches the language.
    do_action( 'wpml_switch_language', sanitize_text_field( $_GET[ 'wpml_lang' ] ) );

    try {
        // Run other content queries.
    } finally {
        // Closes the scope that the call above opened.
        do_action( 'wpml_switch_language', null );
    }
}
在 WP_Query $args[ ‘tax_query’ ][ ‘field’ ] 参数中错误使用“id”值

解决方案:

对“field”参数使用“id”参数适用于默认语言,但不适用于第二种语言。以下是不正确查询的示例:

$args = array(
    'post_type' => 'post',
    'tax_query' => array(
        array(
            'taxonomy' => 'people',
            'field'    => 'id',
            'terms'    => 'bob',
        ),
    ),
);
$query = new WP_Query( $args );

开发者应更正“field”参数。

'field'    => 'id',

改为:

'field'    => 'term_id',

参考: https://codex.wordpress.org/Class_Reference/WP_Query#Taxonomy_Parameters (在新标签页中打开)。“field”参数没有“id”值。其默认值为“term_id”。

作者:Amir