Estendere
EstendereTradurre blocchi Gutenberg aggiuntivi

Tradurre blocchi Gutenberg aggiuntivi

Gato AI Translations for Polylang può tradurre gli articoli basati su blocchi.

Il plugin è dotato di supporto per molti blocchi predefiniti. Per tutto ciò che va oltre — i tuoi blocchi personalizzati, o blocchi di plugin di terze parti che non includono un wpml-config.xml — puoi estendere il supporto tramite hook PHP.

Tradurre le stringhe

Per registrare attributi traducibili aggiuntivi per un blocco, usa il filtro gatompl:gutenberg_block_type_translatable_attribute_regexes.

Perché le espressioni regolari?

Un blocco Gutenberg viene persistito in post_content sotto forma di un commento HTML che contiene gli attributi JSON del blocco, seguito dall'HTML renderizzato del blocco, ad esempio:

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

Tradurre un blocco significa trovare la sottostringa precisa da tradurre all'interno di quel markup, sostituirla con la sua traduzione e lasciare intatto tutto il resto (nome del blocco, altri attributi, struttura HTML, blocchi circostanti). Le espressioni regolari sono il modo in cui il plugin individua esattamente quale sottostringa sostituire: il testo prima e dopo il valore viene catturato in gruppi, e il valore stesso è la parte che viene sostituita.

Attributi stringa standard (memorizzati nel JSON del blocco)

Se la proprietà è una stringa normale memorizzata negli attributi JSON del blocco, passa true e il plugin userà la sua espressione regolare predefinita.

Ad esempio, per tradurre gli attributi daysLabel, hoursLabel, minutesLabel e secondsLabel del blocco kadence/countdown — il cui markup è simile a questo:

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

…registra gli attributi così:

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

Il valore true viene espanso internamente in questa espressione regolare predefinita:

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

…dove i segnaposto sono:

  1. %1$s → il valore dell'attributo
  2. %2$s → il nome dell'attributo
  3. %3$s → il nome del blocco

Per l'attributo daysLabel su kadence/countdown, i segnaposto vengono sostituiti così: %3$s → kadence/countdown, %2$s → daysLabel, %1$s → Days, producendo:

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

Solo Days viene sostituito; il nome del blocco, gli altri attributi e il commento di chiusura vengono preservati dai gruppi di cattura.

La forma dell'espressione regolare è:

#(tutto ciò che precede)valore dell'attributo(tutto ciò che segue)#

Stringhe memorizzate nell'HTML del blocco

Se il valore non è memorizzato negli attributi JSON ma all'interno dell'HTML renderizzato, fornisci la tua espressione regolare. Puoi usare %s (invece di %1$s) dove va il valore dell'attributo, e avere il nome del blocco e il nome dell'attributo codificati direttamente nell'espressione regolare.

Esempio — tradurre l'attributo content del blocco generateblocks/text. Il suo markup è simile a questo — nota che Hello world non è nel JSON, si trova tra i tag renderizzati:

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

L'espressione regolare predefinita non troverebbe mai quella sottostringa, quindi fornisci la tua:

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

Quando lo stesso valore appare in più punti

Se lo stesso attributo appare sia negli attributi JSON sia nell'HTML (o in due punti diversi), passa un array di espressioni regolari — ciascuna deve attivarsi affinché ogni copia della stringa venga tradotta.

Ad esempio, sul blocco generateblocks/media, alt e title sono memorizzati sia all'interno di htmlAttributes nel JSON, sia come attributi HTML sull'<img> renderizzato:

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

Due espressioni regolari per attributo — una che mira al JSON, una che mira all'<img> — garantiscono che entrambe le copie restino sincronizzate dopo la traduzione:

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

Se il valore dell'attributo è un oggetto JSON, puoi mirare a una sotto-proprietà specifica usando un . (punto) nel nome dell'attributo, come mostrato sopra con htmlAttributes.alt e htmlAttributes.title su generateblocks/media.

Disabilitare la traduzione per un attributo tradotto automaticamente

Passare false o null rimuove la traduzione di un attributo che il plugin tradurrebbe altrimenti automaticamente. Questo è utile, ad esempio, per escludere un attributo stringa specifico dalla traduzione automatica nei blocchi solo PHP, o per blocchi importati da un wpml-config.xml di cui non vuoi tradurre gli attributi dichiarati:

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

Tradurre i riferimenti a entità

I riferimenti a entità (un ID di articolo/media/termine/menu memorizzato in un attributo di blocco) possono essere rimappati all'entità corrispondente nella lingua di destinazione al momento della traduzione. Usa uno dei seguenti filtri a seconda del tipo di riferimento:

Tipo di riferimentoFiltro
Custom post e mediagatompl:gutenberg_block_type_custompost_and_media_reference_attribute_regexes
Termini di tassonomiagatompl:gutenberg_block_type_taxonomy_term_reference_attribute_regexes
Menu per IDgatompl:gutenberg_block_type_menu_reference_by_id_attribute_regexes
Menu per sluggatompl:gutenberg_block_type_menu_reference_by_slug_attribute_regexes

Ogni filtro riceve la stessa struttura del filtro degli attributi traducibili (true per l'espressione regolare predefinita, una stringa o un array per le espressioni personalizzate).

Ad esempio, il blocco woocommerce/single-product memorizza il prodotto collegato sotto forma di un productId numerico:

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

Quando l'articolo viene tradotto, quel 42 (il prodotto nella lingua di origine) deve essere rimappato al suo equivalente nella lingua di destinazione (ad esempio 87). Contrassegna productId come riferimento a un custom post in modo che il plugin catturi e sostituisca l'ID al momento della traduzione:

add_filter(
    'gatompl:gutenberg_block_type_custompost_and_media_reference_attribute_regexes',
    static function (array $regexes): array {
        $regexes['woocommerce/single-product'] = [
            'productId' => true,
            // …o un'espressione regolare personalizzata se `productId` non è memorizzato nella forma JSON standard:
            // 'productId' => '#(<!-- wp:woocommerce/single-product \{.*?\"productId\":)%s([,\}].*? /?-->)#',
        ];
        return $regexes;
    }
);

Usa lo stesso schema per gli altri tipi di riferimento. Ogni tipo ha lo stesso aspetto nel markup del blocco — un ID numerico o uno slug incorporato nel JSON — ciò che cambia è il modo in cui il plugin lo risolve nella lingua di destinazione:

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

Scoprire i nomi degli attributi

Il modo più rapido per trovare i nomi degli attributi e come sono memorizzati è eseguire la query GraphQL Translate custom posts ed esaminare il campo di risposta blockFlattenedDataItems per il blocco in questione.

Consulta la guida Recuperare i dati del page builder da tradurre per sapere come eseguire quella query e leggerne l'output.

Aggirare i blocchi i cui attributi necessitano di elaborazione

Gli hook qui sopra presuppongono che il valore dell'attributo esposto tramite blockFlattenedDataItems sia già il valore da tradurre (uno scalare o un array).

Se il valore è incapsulato — ad esempio, l'attributo memorizza <li>Some text</li> e vuoi che venga tradotto solo Some text — devi prima estrarlo tramite il filtro gatompl:gutenberg_block_flattened_data_item_attributes.

Il blocco generateblocks/image è un esempio concreto: i suoi attributi alt e title non sono esposti come attributi autonomi, vivono all'interno dell'HTML di innerContent e devono essere estratti con un'espressione regolare.

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

Una volta che alt e title esistono sull'oggetto degli attributi, gli hook basati sulle espressioni regolari qui sopra possono mirarli come qualsiasi altro attributo.

Dove trovare esempi

Le integrazioni del plugin stesso sono buoni riferimenti concreti. Esplora questi file all'interno del plugin che hai installato:

  • Espressioni regolari degli attributi di blocco: wp-content/plugins/gato-ai-translations-for-polylang/src/Constants/BlockTypeAttributeValues.php
  • Pre-elaborazione degli attributi di blocco: wp-content/plugins/gato-ai-translations-for-polylang/src/ConditionalOnContext/LicenseIsActive/Hooks/CoreBlockFlattenedDataItemAttributesHookSet.php