Узнайте, как использовать пользовательский код PHP и фильтры WPML для ручной регистрации пользовательских виджетов Elementor для перевода.
Существует два типа пользовательских виджетов Elementor:
- Простые виджеты: это виджеты без повторяющихся полей. Вы можете зарегистрировать простые виджеты с помощью плагина Multilingual Tools от WPML, чтобы избежать написания дополнительного кода на PHP.
- Сложные виджеты: виджеты с более сложной структурой. Они могут включать одно или несколько повторяющихся полей.
Чтобы сделать Ваш сложный виджет переводимым с помощью WPML, Вы можете использовать один из двух способов:
- Рекомендуемый: с использованием конфигурационного файла WPML wpml-config.xml. Этот процесс описан в нашем руководстве о том, как зарегистрировать виджеты конструктора страниц для перевода.
- Ручной: с использованием пользовательского кода 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 Вы можете указать следующие элементы:
- field — id поля. Это тот же id, который используется при добавлении элемента управления через функцию Control_stack::add_control.
- type — тип поля. Это текст, отображаемый в Редакторе переводов WPML, который помогает переводчику понять, какое поле нужно перевести.
- 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 приводит к фатальной ошибке.