WPML

了解如何使用自定义 PHP 代码和 WPML 过滤器手动注册自定义 Elementor 小工具以进行翻译。

自定义 Elementor 小工具有两种类型:

要使您的复杂小工具可使用 WPML 翻译,您可以使用以下两种方法之一:

  1. 推荐:使用 wpml-config.xml(WPML 的配置文件)。我们在关于如何注册页面构建器小工具以进行翻译的教程中概述了此过程。
  2. 手动:使用自定义 PHP 代码。如果您想使用此方法,可以遵循本页上的指南。

使用 PHP 添加 WPML 翻译支持

为了演示手动过程,我们采用了 Elementor 的一个小工具,并对其进行了扩展以包含 WPML 支持。您可以在此 GitHub 页面上找到该小工具。

1. 向您的小工具添加 WPML 过滤器

对于每个自定义小工具插件,您应该在其 init 动作期间添加 wpml_elementor_widgets_to_translate 过滤器。WPML 使用此过滤器来收集有关需要翻译的小工具文本的更多信息。

Elementor 小工具的 WPML 过滤器
add_filter( 'wpml_elementor_widgets_to_translate', [ $this, 'wpml_widgets_to_translate_filter' ] );

此过滤器会传递列出所有需要翻译的小工具类型的数组。该数组包含默认的 Elementor 部分以及有关需要翻译的内容的信息。

您应该将任何新的小工具类型添加到此结构中,如下例所示。

添加 Elementor 小工具
public function wpml_widgets_to_translate_filter( $widgets ) {
  $widgets[ $this->get_name() ] = [
     'conditions' => [ 'widgetType' => $this->get_name() ],
     'fields'     => [
        [
           'field'       => 'title',
           'type'        => __( 'Hello World Title', 'hello-world' ),
           'editor_type' => 'LINE'
        ],
     ],
  ];

  return $widgets;
}

2. 创建将处理翻译的自定义类

设置好过滤器后,创建一个自定义类来管理您的小工具的翻译。在 integration-class 字段中指定类名。

指定包含更复杂小工具的自定义类
public function wpml_widgets_to_translate_filter( $widgets ) {
  $widgets[ $this->get_name() ] = [
     'conditions' => [ 'widgetType' => $this->get_name() ],
     'fields'     => [],
      'integration-class' => 'My_Custom_Widget_WPML_Support’,
     ],
  ];

  return $widgets;
}

fields 数组中,您可以指定以下元素:

  1. field – 字段的 id。这与通过 Control_stack::add_control 函数添加控件时使用的 id 相同。
  2. type – 字段的类型。这是显示在 WPML 翻译编辑器中的文本,用于帮助译员了解要翻译的字段。
  3. editor_type – 这是在 WPML 翻译编辑器中使用的文本字段类型。有效值为 LINEAREAVISUAL

3. 实现 IWPML_Page_Builders_Module 接口

集成类需要实现 getupdate 函数。get 函数返回需要翻译的字符串列表,而 update 函数在接收到翻译时更新 Elementor 数据。

包含更复杂小工具的自定义类示例
/**
* Class IWPML_Page_Builders_Module
*/
interface IWPML_Page_Builders_Module {
  /**
   * @param string|int $node_id
   * @param mixed $element
   * @param WPML_PB_String[] $strings
   *
   * @return WPML_PB_String[]
   */
  public function get( $node_id, $element, $strings );

  /**
   * @param string|int $node_id
   * @param mixed $element
   * @param WPML_PB_String $string
   *
   * @return array
   */
  public function update( $node_id, $element, WPML_PB_String $string );
}

4. 使用 field_id 处理区块中相同字段的多次出现

如果在区块中有多次出现的相同字段,请使用 field_id 来描述 Elementor 区块内的字段。这允许您区分节点中相同字段的出现。

相同字段的多次出现
public function wpml_widgets_to_translate_filter( $widgets ) {
 $widgets[ $this->get_name() ] = [
    'conditions' => [ 'widgetType' => $this->get_name() ],
    'fields'     => [
       'title_1' => [
          'field'       => 'title',
          'field_id'   => 'title_1',
          'type'        => __( 'Hello World Title', 'hello-world' ),
          'editor_type' => 'LINE'
       ],
       'title_2' => [
          'field'       => 'title',
          'field_id'   => 'title_2',
          'type'        => __( 'Hello World Title', 'hello-world' ),
          'editor_type' => 'LINE'
       ],
    ],
 ];

 return $widgets;
}

5. 使用 WPML_Elementor_Module_With_Items 类处理包含其他元素列表的小工具

一些 Elementor 小工具(如 Slides 小工具)包含元素列表(例如,带有标题和按钮的多个幻灯片)。如果您的自定义小工具具有类似的列表,您可以扩展 WPML_Elementor_Module_With_Items 类以分别处理每个项目的翻译。

包含其他元素列表的自定义类示例
/**
* Class WPML_Elementor_Slides
*/
class WPML_Elementor_Slides extends WPML_Elementor_Module_With_Items {

  /**
   * @return string
   */
  public function get_items_field() {
     return 'slides';
  }

  /**
   * @return array
   */
  public function get_fields() {
     return array( 'heading', 'description', 'button_text' );
  }

  /**
   * @param string $field
   *
   * @return string
   */
  protected function get_title( $field ) {
     switch( $field ) {
        case 'heading':
           return esc_html__( 'Slides: heading', 'wpml-string-translation' );

        case 'description':
           return esc_html__( 'Slides: description', 'wpml-string-translation' );

        case 'button_text':
           return esc_html__( 'Slides: button text', 'wpml-string-translation' );

        default:
           return '';
     }
  }

  /**
   * @param string $field
   *
   * @return string
   */
  protected function get_editor_type( $field ) {
     switch( $field ) {
        case 'heading':
        case 'button_text':
           return 'LINE';

        case 'description':
           return 'VISUAL';

        default:
           return '';
     }
  }

}

您可以在 WPML 核心插件的以下文件夹中找到更多示例:

  • ..\wp-content\plugins\sitepress-multilingual-cms\addons\wpml-page-builders\classes\Integrations\Elementor\modules\

请确保在 init 钩子上加载类。从 WPML 4.5 开始,在 init 动作钩子之前加载类会导致致命错误。

作者:Amir · 最后更新时间:2024年11月7日