Étendre
ÉtendreTraduire des blocs Gutenberg supplémentaires

Traduire des blocs Gutenberg supplémentaires

Gato AI Translations for Polylang peut traduire les articles basés sur des blocs.

Le plugin est livré avec une prise en charge de nombreux blocs par défaut. Pour tout ce qui va au-delà — vos propres blocs personnalisés, ou des blocs de plugins tiers qui n'incluent pas de wpml-config.xml — vous pouvez étendre la prise en charge via des hooks PHP.

Traduire des chaînes

Pour enregistrer des attributs traduisibles supplémentaires pour un bloc, utilisez le filtre gatompl:gutenberg_block_type_translatable_attribute_regexes.

Pourquoi des expressions régulières ?

Un bloc Gutenberg est persisté dans post_content sous la forme d'un commentaire HTML qui contient les attributs JSON du bloc, suivi du HTML rendu du bloc, par exemple :

<!-- wp:my-plugin/my-block {"title":"Hello"} -->
<div class="wp-block-my-plugin-my-block">Hello</div>
<!-- /wp:my-plugin/my-block -->

Traduire un bloc signifie trouver la sous-chaîne précise à traduire dans ce balisage, la remplacer par sa traduction et laisser tout le reste intact (nom du bloc, autres attributs, structure HTML, blocs environnants). Les expressions régulières permettent au plugin de localiser exactement quelle sous-chaîne remplacer : le texte avant et après la valeur est capturé dans des groupes, et la valeur elle-même est la partie qui est remplacée.

Attributs de chaîne standard (stockés dans le JSON du bloc)

Si la propriété est une chaîne normale stockée dans les attributs JSON du bloc, passez true et le plugin utilisera son expression régulière par défaut.

Par exemple, pour traduire les attributs daysLabel, hoursLabel, minutesLabel et secondsLabel du bloc kadence/countdown — dont le balisage ressemble à ceci :

<!-- wp:kadence/countdown {"uniqueID":"_abc123","date":"2026-12-31 00:00:00","daysLabel":"Days","hoursLabel":"Hours","minutesLabel":"Minutes","secondsLabel":"Seconds"} -->
<div class="wp-block-kadence-countdown">…</div>
<!-- /wp:kadence/countdown -->

…enregistrez les attributs ainsi :

add_filter(
    'gatompl:gutenberg_block_type_translatable_attribute_regexes',
    static function (array $regexes): array {
        $regexes['kadence/countdown'] = [
            'daysLabel'    => true,
            'hoursLabel'   => true,
            'minutesLabel' => true,
            'secondsLabel' => true,
        ];
        return $regexes;
    }
);

La valeur true est développée en interne en cette expression régulière par défaut :

#(<!-- wp:%3$s \{.*?\"%2$s\":\")%1$s(\".*?\}/?-->)#

…où les espaces réservés sont :

  1. %1$s → la valeur de l'attribut
  2. %2$s → le nom de l'attribut
  3. %3$s → le nom du bloc

Pour l'attribut daysLabel sur kadence/countdown, les espaces réservés sont substitués comme suit : %3$skadence/countdown, %2$sdaysLabel, %1$sDays, ce qui produit :

#(<!-- wp:kadence/countdown \{.*?\"daysLabel\":\")Days(\".*?\}/?-->)#

Seul Days est remplacé ; le nom du bloc, les autres attributs et le commentaire de fermeture sont préservés par les groupes de capture.

La forme de l'expression régulière est :

#(tout ce qui précède)valeur de l'attribut(tout ce qui suit)#

Chaînes stockées dans le HTML du bloc

Si la valeur n'est pas stockée dans les attributs JSON mais dans le HTML rendu, fournissez votre propre expression régulière. Vous pouvez utiliser %s (au lieu de %1$s) à l'emplacement de la valeur de l'attribut, et avoir le nom du bloc et de l'attribut codés en dur dans l'expression régulière.

Exemple — traduire l'attribut content du bloc generateblocks/text. Son balisage ressemble à ceci — notez que Hello world n'est pas dans le JSON, il se trouve entre les balises rendues :

<!-- wp:generateblocks/text {"uniqueId":"abc123","tagName":"p"} -->
<p class="gb-text">Hello world</p>
<!-- /wp:generateblocks/text -->

L'expression régulière par défaut ne trouverait jamais cette sous-chaîne, vous fournissez donc la vôtre :

add_filter(
    'gatompl:gutenberg_block_type_translatable_attribute_regexes',
    static function (array $regexes): array {
        $regexes['generateblocks/text'] = [
            'content' => '#(<!-- wp:generateblocks/text [^>]*?-->\n?<[a-z0-9]+ ?[^>]*?>)%s(</[a-z0-9]+>\n?<!-- /wp:generateblocks/text -->)#',
        ];
        return $regexes;
    }
);

Lorsque la même valeur apparaît à plusieurs endroits

Si le même attribut apparaît à la fois dans les attributs JSON et dans le HTML (ou à deux endroits différents), passez un tableau d'expressions régulières — chacune doit se déclencher pour que chaque copie de la chaîne soit traduite.

Par exemple, sur le bloc generateblocks/media, alt et title sont stockés à la fois dans htmlAttributes dans le JSON et en tant qu'attributs HTML sur le <img> rendu :

<!-- wp:generateblocks/media {"mediaId":42,"htmlAttributes":{"alt":"Cat sitting","title":"My cat"}} -->
<figure class="gb-media"><img src="…" alt="Cat sitting" title="My cat"></figure>
<!-- /wp:generateblocks/media -->

Deux expressions régulières par attribut — une ciblant le JSON, une ciblant le <img> — garantissent que les deux copies restent synchronisées après la traduction :

add_filter(
    'gatompl:gutenberg_block_type_translatable_attribute_regexes',
    static function (array $regexes): array {
        $regexes['generateblocks/media'] = [
            'htmlAttributes.alt' => [
                '#(<!-- wp:generateblocks/media \{.*?\"htmlAttributes\":\{.*?\"alt\":\")%s(\".*?\}.*?\} -->)#',
                '#(<!-- wp:generateblocks/media [^>]*?-->\n?.*<img [^>]*alt=\")%s(\"[^>]*?>.*\n?<!-- /wp:generateblocks/media -->)#',
            ],
            'htmlAttributes.title' => [
                '#(<!-- wp:generateblocks/media \{.*?\"htmlAttributes\":\{.*?\"title\":\")%s(\".*?\}.*?\} -->)#',
                '#(<!-- wp:generateblocks/media [^>]*?-->\n?.*<img [^>]*title=\")%s(\"[^>]*?>.*\n?<!-- /wp:generateblocks/media -->)#',
            ],
        ];
        return $regexes;
    }
);

Si la valeur de l'attribut est un objet JSON, vous pouvez cibler une sous-propriété spécifique en utilisant un . (point) dans le nom de l'attribut, comme montré ci-dessus avec htmlAttributes.alt et htmlAttributes.title sur generateblocks/media.

Désactiver la traduction pour un attribut traduit automatiquement

Passer false ou null supprime la traduction d'un attribut que le plugin traduirait autrement automatiquement. C'est utile, par exemple, pour exclure un attribut de chaîne spécifique de la traduction automatique dans les blocs PHP uniquement, ou pour des blocs importés depuis un wpml-config.xml dont vous ne souhaitez pas traduire les attributs déclarés :

add_filter(
    'gatompl:gutenberg_block_type_translatable_attribute_regexes',
    static function (array $regexes): array {
        // Disable translation of the `header` attribute on the
        // `my-plugin/duplicate-alert` block (either form works)
        unset($regexes['my-plugin/duplicate-alert']['header']);
        $regexes['my-plugin/duplicate-alert']['implications'] = false;
        return $regexes;
    }
);

Traduire les références d'entités

Les références d'entités (un ID d'article/média/terme/menu stocké dans un attribut de bloc) peuvent être remappées vers l'entité correspondante dans la langue cible au moment de la traduction. Utilisez l'un des filtres suivants selon le type de référence :

Type de référenceFiltre
Custom posts et médiasgatompl:gutenberg_block_type_custompost_and_media_reference_attribute_regexes
Termes de taxonomiegatompl:gutenberg_block_type_taxonomy_term_reference_attribute_regexes
Menus par IDgatompl:gutenberg_block_type_menu_reference_by_id_attribute_regexes
Menus par sluggatompl:gutenberg_block_type_menu_reference_by_slug_attribute_regexes

Chaque filtre reçoit la même structure que le filtre des attributs traduisibles (true pour l'expression régulière par défaut, une chaîne ou un tableau pour les expressions personnalisées).

Par exemple, le bloc woocommerce/single-product stocke le produit lié sous la forme d'un productId numérique :

<!-- wp:woocommerce/single-product {"productId":42} /-->

Lorsque l'article est traduit, ce 42 (le produit en langue source) doit être remappé vers son équivalent en langue cible (par exemple 87). Marquez productId comme référence à un custom post pour que le plugin capture et remplace l'ID au moment de la traduction :

add_filter(
    'gatompl:gutenberg_block_type_custompost_and_media_reference_attribute_regexes',
    static function (array $regexes): array {
        $regexes['woocommerce/single-product'] = [
            'productId' => true,
            // …ou une expression régulière personnalisée si `productId` n'est pas stocké dans la forme JSON standard :
            // 'productId' => '#(<!-- wp:woocommerce/single-product \{.*?\"productId\":)%s([,\}].*? /?-->)#',
        ];
        return $regexes;
    }
);

Utilisez le même schéma pour les autres types de référence. Chaque type a le même aspect dans le balisage du bloc — un ID numérique ou un slug intégré dans le JSON — ce qui diffère, c'est la façon dont le plugin le résout dans la langue cible :

<!-- wp:my-plugin/related-category {"categoryId":17} /-->
<!-- wp:my-plugin/menu-picker {"menuId":5} /-->
<!-- wp:my-plugin/menu-picker {"menuSlug":"main-nav"} /-->
// Taxonomy term reference
add_filter(
    'gatompl:gutenberg_block_type_taxonomy_term_reference_attribute_regexes',
    static function (array $regexes): array {
        $regexes['my-plugin/related-category'] = [
            'categoryId' => true,
        ];
        return $regexes;
    }
);
 
// Menu reference by ID
add_filter(
    'gatompl:gutenberg_block_type_menu_reference_by_id_attribute_regexes',
    static function (array $regexes): array {
        $regexes['my-plugin/menu-picker'] = [
            'menuId' => true,
        ];
        return $regexes;
    }
);
 
// Menu reference by slug
add_filter(
    'gatompl:gutenberg_block_type_menu_reference_by_slug_attribute_regexes',
    static function (array $regexes): array {
        $regexes['my-plugin/menu-picker'] = [
            'menuSlug' => true,
        ];
        return $regexes;
    }
);

Découvrir les noms des attributs

La façon la plus rapide de trouver les noms des attributs et comment ils sont stockés est d'exécuter la query GraphQL Translate custom posts et d'examiner le champ de réponse blockFlattenedDataItems pour le bloc en question.

Consultez le guide Obtenir les données du page builder à traduire pour savoir comment exécuter cette query et lire sa sortie.

Travailler autour des blocs dont les attributs nécessitent un traitement

Les hooks ci-dessus supposent que la valeur de l'attribut exposée via blockFlattenedDataItems est déjà la valeur à traduire (un scalaire ou un tableau).

Si la valeur est encapsulée — par exemple, l'attribut stocke <li>Some text</li> et vous voulez uniquement que Some text soit traduit — vous devez d'abord l'extraire via le filtre gatompl:gutenberg_block_flattened_data_item_attributes.

Le bloc generateblocks/image est un exemple concret : ses attributs alt et title ne sont pas exposés comme des attributs autonomes, ils vivent dans le HTML de innerContent et doivent être extraits avec une expression régulière.

add_filter(
    'gatompl:gutenberg_block_flattened_data_item_attributes',
    static function (?\stdClass $attributes, string $blockTypeName, \stdClass $blockDataItem): ?\stdClass {
        if ($attributes === null || $blockTypeName !== 'generateblocks/image') {
            return $attributes;
        }
 
        $innerContent = $blockDataItem->innerContent ?? null;
        if (!is_array($innerContent) || !isset($innerContent[0]) || !is_string($innerContent[0])) {
            return $attributes;
        }
        $html = $innerContent[0];
 
        if (preg_match('#<img [^>]*alt="([^"]*)"[^>]*?>#', $html, $matches) === 1 && $matches[1] !== '') {
            $attributes->alt = $matches[1];
        }
        if (preg_match('#<img [^>]*title="([^"]*)"[^>]*?>#', $html, $matches) === 1 && $matches[1] !== '') {
            $attributes->title = $matches[1];
        }
        return $attributes;
    },
    10,
    3
);

Une fois que alt et title existent sur l'objet d'attributs, les hooks basés sur les expressions régulières ci-dessus peuvent les cibler comme n'importe quel autre attribut.

Où trouver des exemples

Les propres intégrations du plugin sont de bonnes références concrètes. Explorez ces fichiers dans le plugin que vous avez installé :

  • Expressions régulières des attributs de bloc : wp-content/plugins/gato-ai-translations-for-polylang/src/Constants/BlockTypeAttributeValues.php
  • Pré-traitement des attributs de bloc : wp-content/plugins/gato-ai-translations-for-polylang/src/ConditionalOnContext/LicenseIsActive/Hooks/CoreBlockFlattenedDataItemAttributesHookSet.php