WPML

Узнайте, как использовать пользовательский код PHP и фильтры WPML для ручной регистрации пользовательских виджетов Elementor для перевода.

Существует два типа пользовательских виджетов Elementor:

Чтобы сделать Ваш сложный виджет переводимым с помощью WPML, Вы можете использовать один из двух способов:

  1. Рекомендуемый: с использованием конфигурационного файла WPML wpml-config.xml. Этот процесс описан в нашем руководстве о том, как зарегистрировать виджеты конструктора страниц для перевода.
  2. Ручной: с использованием пользовательского кода PHP. Если Вы хотите использовать этот метод, следуйте инструкциям на этой странице.

Добавление поддержки перевода WPML с помощью PHP

Для демонстрации ручного процесса мы взяли один из виджетов Elementor и расширили его, добавив поддержку WPML. Вы можете найти этот виджет на этой странице GitHub.

1. Добавьте фильтр WPML в Ваш виджет

Для каждого плагина с пользовательскими виджетами Вам следует добавить фильтр wpml_elementor_widgets_to_translate во время их действия init. WPML использует этот фильтр для сбора дополнительной информации о текстах виджета, которые нуждаются в переводе.

Фильтр WPML для виджетов Elementor
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. fieldid поля. Это тот же id, который используется при добавлении элемента управления через функцию Control_stack::add_control.
  2. type — тип поля. Это текст, отображаемый в Редакторе переводов WPML, который помогает переводчику понять, какое поле нужно перевести.
  3. editor_type — тип текстового поля, используемого в редакторе переводов WPML. Допустимые значения: LINE, AREA и VISUAL.

3. Реализуйте интерфейс IWPML_Page_Builders_Module

Класс интеграции должен реализовывать функции get и update. Функция 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 · Последнее обновление: 7 ноября 2024