Découvrez comment utiliser du code PHP personnalisé et des filtres WPML pour enregistrer manuellement des widgets Elementor personnalisés pour la traduction.
Il existe deux types de widgets Elementor personnalisés :
- Widgets simples : ce sont des widgets sans champs répéteurs. Vous pouvez enregistrer des widgets simples à l’aide de l’extension Multilingual Tools de WPML pour éviter de coder en PHP.
- Widgets complexes : ce sont des widgets avec des structures plus compliquées. Ils peuvent inclure un ou plusieurs champs répéteurs.
Pour rendre votre widget complexe traduisible avec WPML, vous pouvez utiliser l’une des deux méthodes suivantes :
- Recommandé : utiliser wpml-config.xml, le fichier de configuration de WPML. Le processus est décrit dans notre tutoriel expliquant comment enregistrer les widgets des constructeurs de pages pour la traduction.
- Manuel : utiliser du code PHP personnalisé. Si vous souhaitez utiliser cette méthode, vous pouvez suivre les directives de cette page.
Ajouter la prise en charge de la traduction WPML avec PHP
Pour démontrer le processus manuel, nous avons pris l’un des widgets d’Elementor et l’avons étendu pour inclure la compatibilité avec WPML. Vous pouvez trouver le widget sur cette page GitHub.
1. Ajoutez un filtre WPML à votre widget
Pour chaque extension de widget personnalisé, vous devez ajouter le filtre wpml_elementor_widgets_to_translate lors de leur action init. WPML utilise ce filtre pour recueillir plus d’informations sur les textes du widget qui nécessitent une traduction.
Filtre WPML pour les widgets Elementor
add_filter( 'wpml_elementor_widgets_to_translate', [ $this, 'wpml_widgets_to_translate_filter' ] );
Ce filtre transmet le tableau qui liste tous les types de widgets à traduire. Ce tableau comprend les parties par défaut d’Elementor et des informations sur ce qui doit être traduit.
Vous devez ajouter tout nouveau type de widget à cette structure, comme dans l’exemple suivant.
Ajout de widgets 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. Créez une classe personnalisée qui gérera les traductions
Une fois le filtre en place, créez une classe personnalisée pour gérer les traductions de votre widget. Spécifiez le nom de la classe dans le champ integration-class.
Spécification d’une classe personnalisée comportant des widgets plus compliqués
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;
}Dans le tableau fields, vous pouvez spécifier les éléments suivants :
- field – L’id du champ. Il s’agit du même id que celui utilisé lors de l’ajout d’un contrôle via la fonction Control_stack::add_control.
- type – Le type de champ. Il s’agit du texte affiché dans l’Éditeur de traduction WPML pour aider le traducteur à savoir quel champ doit être traduit.
- editor_type – Il s’agit du type de champ de texte utilisé dans l’Éditeur de traduction WPML. Les valeurs valides sont LINE, AREA et VISUAL.
3. Implémentez l’interface IWPML_Page_Builders_Module
La classe d’intégration doit implémenter les fonctions get et update. La fonction get renvoie la liste des chaînes de texte nécessitant une traduction et la fonction update met à jour les données d’Elementor lorsqu’une traduction est reçue.
Exemple d’une classe personnalisée comportant des widgets plus compliqués
/**
* 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. Gérez les occurrences multiples du même champ dans un bloc à l’aide de field_id
Si vous avez plusieurs occurrences du même champ à l’intérieur d’un bloc, utilisez le field_id pour décrire un champ à l’intérieur d’un bloc Elementor. Cela vous permet de différencier les occurrences du même champ dans un nœud.
Occurrences multiples du même champ
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. Gérez les widgets avec des listes d’autres éléments à l’aide de la classe WPML_Elementor_Module_With_Items
Certains widgets Elementor, comme le widget Slides, contiennent des listes d’éléments (par exemple, plusieurs diapositives avec des titres et des boutons). Si votre widget personnalisé comporte des listes similaires, vous pouvez étendre la classe WPML_Elementor_Module_With_Items pour gérer la traduction de chaque élément individuellement.
Exemple d’une classe personnalisée comportant une liste d’autres éléments
/**
* 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 '';
}
}
}Vous trouverez d’autres exemples dans le dossier suivant de l’extension noyau de WPML :
- ..\wp-content\plugins\sitepress-multilingual-cms\addons\wpml-page-builders\classes\Integrations\Elementor\modules\
Assurez-vous de charger les classes sur le hook init . À partir de WPML 4.5, le chargement des classes avant le hook d’action init entraîne une erreur fatale.