Uitbreiden
UitbreidenExtra Gutenberg-blokken vertalen

Extra Gutenberg-blokken vertalen

Gato AI Translations for Polylang kan op blokken gebaseerde berichten vertalen.

De plugin wordt geleverd met ondersteuning voor veel blokken direct na installatie. Voor alles daarbuiten — je eigen aangepaste blokken, of blokken van plugins van derden die geen wpml-config.xml meesturen — kun je ondersteuning uitbreiden via PHP-hooks.

Teksten vertalen

Om extra vertaalbare attributen voor een blok te registreren, gebruik je het filter gatompl:gutenberg_block_type_translatable_attribute_regexes.

Waarom reguliere expressies?

Een Gutenberg-blok wordt opgeslagen in post_content als een HTML-commentaar dat de JSON-attributen van het blok bevat, gevolgd door de gerenderde HTML van het blok, bijvoorbeeld:

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

Een blok vertalen betekent de specifieke deelstring vinden die vertaald moet worden in die markup, deze vervangen door de vertaling, en al het andere ongewijzigd laten (bloknaam, andere attributen, HTML-structuur, omliggende blokken). Reguliere expressies zijn de manier waarop de plugin precies aanwijst welke deelstring vervangen moet worden: de tekst voor en na de waarde wordt vastgelegd in groepen, en de waarde zelf is het deel dat wordt omgewisseld.

Standaard tekstattributen (opgeslagen in de JSON van het blok)

Als de eigenschap een gewone tekst is die is opgeslagen in de JSON-attributen van het blok, geef je true mee en gebruikt de plugin zijn standaard reguliere expressie.

Bijvoorbeeld, om de attributen daysLabel, hoursLabel, minutesLabel en secondsLabel van het kadence/countdown-blok te vertalen — waarvan de markup er zo uitziet:

<!-- 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 -->

…registreer je de attributen via:

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;
    }
);

De waarde true wordt intern uitgebreid tot deze standaard reguliere expressie:

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

…waarbij de placeholders zijn:

  1. %1$s → de attribuutwaarde
  2. %2$s → de attribuutnaam
  3. %3$s → de bloknaam

Voor het attribuut daysLabel op kadence/countdown worden de placeholders ingevuld als %3$s → kadence/countdown, %2$s → daysLabel, %1$s → Days, wat oplevert:

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

Alleen Days wordt vervangen; de bloknaam, de andere attributen en het sluitende commentaar worden bewaard door de vastleggroepen.

De vorm van de reguliere expressie is:

#(alles ervoor)attribuutwaarde(alles erna)#

Teksten opgeslagen in de HTML van het blok

Als de waarde niet is opgeslagen in de JSON-attributen maar in de gerenderde HTML, geef je je eigen reguliere expressie mee. Je kunt %s (in plaats van %1$s) gebruiken op de plek van de attribuutwaarde, en de blok- en attribuutnaam hardcoden in de reguliere expressie.

Voorbeeld — het attribuut content van het generateblocks/text-blok vertalen. De markup ziet er zo uit — let op dat Hello world niet in de JSON staat, maar tussen de gerenderde tags:

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

De standaard reguliere expressie zou die deelstring nooit vinden, dus geef je je eigen expressie mee:

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;
    }
);

Wanneer dezelfde waarde op meerdere plaatsen voorkomt

Als hetzelfde attribuut zowel in de JSON-attributen als in de HTML voorkomt (of op twee verschillende plekken), geef je een array van reguliere expressies mee — elke expressie moet worden uitgevoerd zodat alle kopieën van de tekst worden vertaald.

Bijvoorbeeld, in het generateblocks/media-blok worden alt en title zowel opgeslagen in htmlAttributes in de JSON als als HTML-attributen op de gerenderde <img>:

<!-- 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 -->

Twee reguliere expressies per attribuut — een gericht op de JSON, een op de <img> — zorgen ervoor dat beide kopieën na vertaling gesynchroniseerd blijven:

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;
    }
);

Als de attribuutwaarde een JSON-object is, kun je een specifieke sub-eigenschap aanwijzen met een . (punt) in de attribuutnaam, zoals hierboven getoond met htmlAttributes.alt en htmlAttributes.title op generateblocks/media.

Vertaling uitschakelen voor een automatisch vertaald attribuut

false of null doorgeven verwijdert de vertaling voor een attribuut dat de plugin anders automatisch zou vertalen. Dit is handig om bijvoorbeeld een specifiek tekstattribuut uit te sluiten van automatische vertaling in PHP-only blokken, of voor blokken uit een wpml-config.xml waarvan je de gedeclareerde attributen niet wilt vertalen:

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;
    }
);

Entiteitsverwijzingen vertalen

Entiteitsverwijzingen (een post-, media-, term- of menu-ID opgeslagen in een blokattribuut) kunnen worden omgezet naar de overeenkomstige entiteit in de doeltaal op het moment van vertaling. Gebruik een van de volgende filters afhankelijk van het soort verwijzing:

Soort verwijzingFilter
Custom posts en mediagatompl:gutenberg_block_type_custompost_and_media_reference_attribute_regexes
Taxonomietermengatompl:gutenberg_block_type_taxonomy_term_reference_attribute_regexes
Menu's op IDgatompl:gutenberg_block_type_menu_reference_by_id_attribute_regexes
Menu's op sluggatompl:gutenberg_block_type_menu_reference_by_slug_attribute_regexes

Elk filter ontvangt dezelfde structuur als het filter voor vertaalbare attributen (true voor de standaard reguliere expressie, een string of array voor aangepaste expressies).

Bijvoorbeeld, het woocommerce/single-product-blok slaat het gekoppelde product op als een numeriek productId:

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

Wanneer het bericht wordt vertaald, moet dat 42 (het product in de brontaal) worden omgezet naar het equivalent in de doeltaal (stel 87). Markeer productId als een custom-post-verwijzing zodat de plugin het ID vastlegt en omwisselt op het moment van vertaling:

add_filter(
    'gatompl:gutenberg_block_type_custompost_and_media_reference_attribute_regexes',
    static function (array $regexes): array {
        $regexes['woocommerce/single-product'] = [
            'productId' => true,
            // …of een aangepaste reguliere expressie als `productId` niet in het standaard JSON-formaat is opgeslagen:
            // 'productId' => '#(<!-- wp:woocommerce/single-product \{.*?\"productId\":)%s([,\}].*? /?-->)#',
        ];
        return $regexes;
    }
);

Gebruik hetzelfde patroon voor de andere soorten verwijzingen. Elk soort ziet er hetzelfde uit in de blokmarkup — een numeriek ID of een slug ingebed in de JSON — wat verschilt is hoe de plugin het omzet naar de doeltaal:

<!-- 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;
    }
);

Attribuutnamen ontdekken

De snelste manier om de attribuutnamen en hoe ze zijn opgeslagen te vinden, is de GraphQL-query Translate custom posts uitvoeren en het antwoordveld blockFlattenedDataItems voor het betreffende blok bekijken.

Zie de handleiding Pagina-builder-gegevens ophalen om te vertalen voor informatie over hoe je die query uitvoert en de uitvoer leest.

Omgaan met blokken waarvan attributen verwerking nodig hebben

De bovenstaande hooks gaan ervan uit dat de attribuutwaarde die via blockFlattenedDataItems wordt aangeboden al de te vertalen waarde is (een scalar of array).

Als de waarde is ingepakt — bijvoorbeeld slaat het attribuut <li>Some text</li> op en wil je alleen Some text vertalen — moet je het eerst uitpakken via het filter gatompl:gutenberg_block_flattened_data_item_attributes.

Het generateblocks/image-blok is een echt voorbeeld: de attributen alt en title worden niet als zelfstandige attributen aangeboden, maar bevinden zich in de innerContent-HTML en moeten met een reguliere expressie worden uitgelezen.

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
);

Zodra alt en title beschikbaar zijn in het attribuutobject, kunnen de op reguliere expressies gebaseerde hooks hierboven ze aanwijzen als elk ander attribuut.

Waar je voorbeelden kunt vinden

De eigen integraties van de plugin zijn goede praktijkvoorbeelden. Verken deze bestanden in de geinstalleerde plugin:

  • Reguliere expressies voor blokattributen: wp-content/plugins/gato-ai-translations-for-polylang/src/Constants/BlockTypeAttributeValues.php
  • Voorverwerking van blokattributen: wp-content/plugins/gato-ai-translations-for-polylang/src/ConditionalOnContext/LicenseIsActive/Hooks/CoreBlockFlattenedDataItemAttributesHookSet.php