Genişletme
GenişletmeEk Gutenberg bloklarını çevirmek

Ek Gutenberg bloklarını çevirmek

Gato AI Translations for Polylang, blok tabanlı yazıları çevirebilir.

Eklenti, pek çok blok için hazır destek ile birlikte gelir. Bunun ötesinde — kendi özel bloklarınız ya da wpml-config.xml içermeyen üçüncü taraf eklentilerin blokları — için PHP kancaları aracılığıyla desteği genişletebilirsiniz.

Dizeleri çevirmek

Bir blok için ek çevrilebilir özellikler kaydetmek üzere gatompl:gutenberg_block_type_translatable_attribute_regexes filtresini kullanın.

Neden regex?

Bir Gutenberg bloğu, post_content alanına blok JSON özelliklerini taşıyan bir HTML yorumu ve ardından bloğun işlenmiş HTML'si olarak kaydedilir; örneğin:

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

Bir bloğu çevirmek demek, o işaretleme içinde çevrilecek belirli alt dizeyi bulmak, onu çevirisiyle değiştirmek ve geri kalan her şeyi olduğu gibi bırakmak (blok adı, diğer özellikler, HTML yapısı, çevresindeki bloklar) demektir. Regex'ler, eklentinin hangi alt dizeyi değiştireceğini tam olarak belirlemesini sağlar: değerin öncesi ve sonrasındaki kalıp gruplara alınır, değerin kendisi ise değiştirilen kısımdır.

Standart dize özellikleri (bloğun JSON'unda saklanan)

Özellik, bloğun JSON özelliklerinde saklanan normal bir dize ise true geçin; eklenti kendi varsayılan regex'ini kullanır.

Örneğin, kadence/countdown bloğunun daysLabel, hoursLabel, minutesLabel ve secondsLabel özelliklerini çevirmek için — işaretlemesi şöyle görünen:

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

…özellikleri şu şekilde kaydedin:

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

true değeri dahili olarak şu varsayılan regex'e genişletilir:

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

…yer tutucular şunlardır:

  1. %1$s → özellik değeri
  2. %2$s → özellik adı
  3. %3$s → blok adı

kadence/countdown üzerindeki daysLabel özelliği için yer tutucular şöyle yerleştirilir: %3$skadence/countdown, %2$sdaysLabel, %1$sDays, sonuç olarak:

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

Yalnızca Days değiştirilir; blok adı, diğer özellikler ve kapanış yorumu yakalama grupları tarafından korunur.

Regex'in genel yapısı şöyledir:

#(öncesindeki her şey)özellik değeri(sonrasındaki her şey)#

Bloğun HTML'sinde saklanan dizeler

Değer JSON özelliklerinde değil de işlenmiş HTML içinde saklanıyorsa kendi regex'inizi sağlayın. Özellik değerinin gireceği yerde %1$s yerine %s kullanabilir; blok adını ve özellik adını doğrudan regex içine sabit olarak yazabilirsiniz.

Örnek — generateblocks/text bloğunun content özelliğini çevirmek. İşaretlemesi şöyle görünür — Hello world'ün JSON içinde olmadığına, işlenmiş etiketler arasında yer aldığına dikkat edin:

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

Varsayılan regex o alt dizeyi hiçbir zaman bulamaz, bu yüzden kendinizinkini sağlayın:

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

Aynı değer birden fazla yerde göründüğünde

Aynı özellik hem JSON özelliklerinde hem de HTML'de (ya da iki farklı yerde) görünüyorsa bir regex dizisi geçin — dizenin her kopyasının çevrilmesi için her birinin tetiklenmesi gerekir.

Örneğin, generateblocks/media bloğunda alt ve title hem JSON içindeki htmlAttributes altında hem de işlenmiş <img> üzerinde HTML özelliği olarak saklanır:

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

Özellik başına iki regex — biri JSON'u, diğeri <img>'yi hedefleyen — çeviri sonrasında her iki kopyanın senkronize kalmasını sağlar:

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

Özellik değeri bir JSON nesnesi ise, yukarıda generateblocks/media üzerinde htmlAttributes.alt ve htmlAttributes.title ile gösterildiği gibi, özellik adında . (nokta) kullanarak belirli bir alt özelliği hedefleyebilirsiniz.

Otomatik olarak çevrilen bir özellik için çeviriyi devre dışı bırakmak

false veya null geçmek, eklentinin normalde otomatik olarak çevireceği bir özellik için çeviriyi kaldırır. Bu, örneğin yalnızca PHP bloklarındaki belirli bir dize özelliğini otomatik çevirinin dışında tutmak için ya da çevrilmesini istemediğiniz özellikler bildiren bir wpml-config.xml üzerinden gelen bloklar için kullanışlıdır:

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

Varlık referanslarını çevirmek

Varlık referansları (bir blok özelliğinde saklanan yazı/medya/terim/menü kimliği), çeviri sırasında hedef dildeki karşılık gelen varlığa yeniden eşleştirilebilir. Referans türüne göre aşağıdaki filtrelerden birini kullanın:

Referans türüFiltre
Özel yazılar ve medyagatompl:gutenberg_block_type_custompost_and_media_reference_attribute_regexes
Taksonomi terimlerigatompl:gutenberg_block_type_taxonomy_term_reference_attribute_regexes
Kimliğe göre menülergatompl:gutenberg_block_type_menu_reference_by_id_attribute_regexes
Slug'a göre menülergatompl:gutenberg_block_type_menu_reference_by_slug_attribute_regexes

Her filtre, çevrilebilir özellikler filtresuyle aynı yapıyı alır (varsayılan regex için true, özel regex için bir dize veya dizi).

Örneğin, woocommerce/single-product bloğu bağlı ürünü sayısal bir productId olarak saklar:

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

Yazı çevrildiğinde, o 42 (kaynak dildeki ürün) hedef dildeki karşılığına (örneğin 87) yeniden eşleştirilmesi gerekir. Eklentinin çeviri sırasında kimliği yakalayıp değiştirmesi için productId'yi özel yazı referansı olarak işaretleyin:

add_filter(
    'gatompl:gutenberg_block_type_custompost_and_media_reference_attribute_regexes',
    static function (array $regexes): array {
        $regexes['woocommerce/single-product'] = [
            'productId' => true,
            // …ya da `productId` standart JSON biçiminde saklanmıyorsa özel regex:
            // 'productId' => '#(<!-- wp:woocommerce/single-product \{.*?\"productId\":)%s([,\}].*? /?-->)#',
        ];
        return $regexes;
    }
);

Diğer referans türleri için aynı kalıbı kullanın. Her tür blok işaretlemesinde aynı görünür — JSON'a gömülü sayısal bir kimlik veya slug — farklı olan, eklentinin bunu hedef dile nasıl çözümlediğidir:

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

Özellik adlarını keşfetmek

Özellik adlarını ve nasıl saklandıklarını bulmanın en hızlı yolu, Translate custom posts GraphQL sorgusunu çalıştırmak ve söz konusu blok için blockFlattenedDataItems yanıt alanını incelemektir.

Bu sorguyu nasıl çalıştıracağınızı ve çıktısını nasıl okuyacağınızı öğrenmek için Çevrilecek sayfa oluşturucu verilerini alma kılavuzuna bakın.

Özelliklerinin işlenmesi gereken blokları aşmak

Yukarıdaki kancalar, blockFlattenedDataItems aracılığıyla sunulan özellik değerinin zaten çevrilecek değer (skaler veya dizi) olduğunu varsayar.

Değer sarmalanmışsa — örneğin özellik <li>Bir metin</li> saklıyor ve yalnızca Bir metin'in çevrilmesini istiyorsanız — önce gatompl:gutenberg_block_flattened_data_item_attributes filtresi aracılığıyla onu çıkarmanız gerekir.

generateblocks/image bloğu gerçek dünyadan bir örnektir: alt ve title özellikleri bağımsız özellikler olarak sunulmaz; innerContent HTML'sinin içinde yaşarlar ve bir regex ile çıkarılmaları gerekir.

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

alt ve title özellikler nesnesinde yer aldıktan sonra, yukarıdaki regex tabanlı kancalar bunları diğer herhangi bir özellik gibi hedefleyebilir.

Örnekleri nerede bulabilirsiniz

Eklentinin kendi entegrasyonları iyi gerçek dünya referanslarıdır. Kurduğunuz eklentinin içindeki şu dosyaları inceleyin:

  • Blok özelliği regex'leri: wp-content/plugins/gato-ai-translations-for-polylang/src/Constants/BlockTypeAttributeValues.php
  • Blok özelliklerinin ön işlenmesi: wp-content/plugins/gato-ai-translations-for-polylang/src/ConditionalOnContext/LicenseIsActive/Hooks/CoreBlockFlattenedDataItemAttributesHookSet.php