
# WPML

WPML перекладає атрибути користувацького блоку лише в межах, визначених файлом мовної конфігурації. Blockstudio зберігає значення всіх полів у коментарі блоку під `blockstudio.attributes`, тому для кожного блоку потрібен запис, який указує WPML на його текстові поля та ідентифікатори вкладень. Команда `wp bs wpml config` створює такі записи для кожного зареєстрованого блоку.

## Чому блокам потрібна конфігурація

WPML зчитує конфігурацію з файлу з назвою `wpml-config.xml` у кореневій папці активної теми та кожного активного плагіна. Для must-use плагіна, який складається з одного файлу, папка має назву файлу без `.php`. Див. [Файли конфігурації мов](https://wpml.org/documentation/support/language-configuration-files/) та [Як зробити блоки Gutenberg перекладними](https://wpml.org/documentation/support/language-configuration-files/make-custom-gutenberg-blocks-translatable/).

Для блока без запису WPML автоматично виявляє рядки й пропонує для перекладу кожен рядковий атрибут блока. Для блока Blockstudio це стосується значень списків вибору, посилань на файли, URL-адрес і класів CSS. Перекладачі бачать ці технічні значення поруч зі справжнім текстом, а перекладене значення списку вибору або класу може порушити роботу блока.

## Створення конфігурації

Виведіть конфігурацію та збережіть її в кореневій папці теми або плагіна, що містить блоки:

```bash
wp bs wpml config > wp-content/themes/my-theme/wpml-config.xml
```

Або дозвольте команді записати файл:

```bash
wp bs wpml config --file=wp-content/themes/my-theme/wpml-config.xml
```

Блок із текстовим полем, зображенням, посиланням і повторювачем:

```json title="block.json"
{
  "name": "my-theme/cards",
  "title": "Cards",
  "blockstudio": {
    "attributes": [
      { "id": "heading", "type": "text", "label": "Heading" },
      { "id": "gallery", "type": "files", "label": "Gallery", "multiple": true },
      {
        "id": "style",
        "type": "select",
        "label": "Style",
        "options": [
          { "value": "light", "label": "Light" },
          { "value": "dark", "label": "Dark" }
        ]
      },
      {
        "id": "cards",
        "type": "repeater",
        "label": "Cards",
        "attributes": [
          { "id": "title", "type": "text", "label": "Title" },
          { "id": "image", "type": "files", "label": "Image" },
          { "id": "link", "type": "link", "label": "Button" }
        ]
      }
    ]
  }
}
```

перетворюється на:

```xml title="wpml-config.xml"
<wpml-config>
	<gutenberg-blocks>
		<!-- blockstudio:start -->
		<!-- Generated by wp bs wpml config. Run it again after changing block fields; edits between the markers are replaced. -->
		<gutenberg-block type="my-theme/cards" translate="1" label="Cards">
			<key name="blockstudio">
				<key name="attributes">
					<key name="heading" label="Heading" />
					<key name="gallery">
						<key name="*" type="post-ids" sub-type="attachment" />
					</key>
					<key name="cards">
						<key name="*">
							<key name="title" label="Cards: Title" />
							<key name="image" type="post-ids" sub-type="attachment" />
							<key name="link">
								<key name="title" label="Cards: Button: Link text" />
								<key name="url" type="link" label="Cards: Button: URL" />
							</key>
						</key>
					</key>
				</key>
			</key>
		</gutenberg-block>
		<!-- blockstudio:end -->
	</gutenberg-blocks>
</wpml-config>
```

Значення `style` не оголошено, тому WPML копіює його в переклад без змін. Ідентифікатори `gallery` та `image` також копіюються, а під час відображення блока WPML замінює кожен із них вкладенням для мови сторінки, тож перекладене зображення може мати власний альтернативний текст. Див. «Автоматичне перетворення ідентифікаторів у блоках» у розділі [Як зробити блоки Gutenberg перекладними](https://wpml.org/documentation/support/language-configuration-files/make-custom-gutenberg-blocks-translatable/). Якщо вкладення не має перекладу, WPML залишає початковий ідентифікатор.

## Що оголошується

Команда зчитує зареєстровані блоки після розгортання полів `custom/` і полів блока та застосування перевизначень і фільтрів атрибутів. Включаються поля, які [розширення](https://blockstudio.dev/uk/docs/extensions/) додають до блока Blockstudio. Поля, які розширення додають до основних блоків або блоків інших плагінів, не включаються, адже ці блоки отримують конфігурацію з WPML або від власного плагіна.

| Поле | Оголошення |
| --- | --- |
| `text`, `textarea`, `richtext`, `wysiwyg` | Текст, який можна перекладати. |
| `link` | `title` як текст і `url` з `type="link"`, тож WPML замінює посилання його перекладом, якщо він доступний. |
| `files` | Збережений ідентифікатор вкладення з `type="post-ids"` та `sub-type="attachment"`. Для `multiple` — рівень із назвою `*` для списку, який також відповідає одному ідентифікатору, що зберігає поле, коли вибрано один файл. |
| `repeater` | Рівень із назвою `*`, що відповідає кожному рядку, з оголошеннями полів рядка. Вкладені повторювачі працюють так само. |
| `group` з `id` | Поля групи, де ідентифікатор групи є префіксом ключа (`cta_text` для поля `text` у групі `cta`). |
| `group` без `id`, `tabs` | Поля без власного рівня. |
| Власний тип поля, зареєстрований із `translate` зі значенням `true` | Текст, який можна перекладати, як і поле `text`. |
| Усі інші вбудовані типи | Не оголошуються. WPML копіює значення без змін. |

Блок без оголошеного текстового поля отримує `translate="0"`. Потім WPML копіює всі його значення й не пропонує нічого з нього для перекладу. Його поля `files` все одно оголошуються в записі, оскільки WPML перетворює ідентифікатори вкладень незалежно від того, що вказує `translate`. Внутрішні блоки перекладаються як зазвичай.

Не оголошуються:

- Поля з `hidden`, оскільки редактори не записують їхні значення.
- Поля з `"translate": false`; див. нижче.
- Поля [власних типів полів](https://blockstudio.dev/uk/docs/blocks/attributes/custom-field-types/), які не зареєстровані з `translate` зі значенням `true`. Для кожного з них команда виводить попередження, оскільки лише тип поля знає, чи містить його значення текст. Явне `"translate": false` для поля також вимикає це попередження для нього. Див. нижче.
- Атрибути, оголошені блоком у його вбудованому `attributes`, а не як поля Blockstudio.
- Ключі сховища, поля яких мають різні типи; див. нижче.

Оголошується кожне текстове поле, зокрема те, що містить технічне значення, як-от клас CSS, якщо для нього не задано `"translate": false`.

### Виключення поля

Текстове поле може містити значення, яке має бути однаковим усіма мовами: ім’я облікового запису, адресу електронної пошти, якір або клас CSS. WPML пропонує його для перекладу, як будь-який інший текст, і перекладене значення може порушити роботу блока. Установіть для `translate` значення `false`, щоб виключити поле з конфігурації, і WPML скопіює його значення в переклад без змін:

```json title="block.json"
{
  "id": "account",
  "type": "text",
  "label": "Account handle",
  "translate": false
}
```

Для `group`, `tabs` або `repeater` `"translate": false` застосовується до кожного поля всередині, зокрема вкладених контейнерів. Дочірній елемент не може скасувати виключення контейнера за допомогою `"translate": true`. Для поля `files` `false` також виключає ідентифікатори вкладень, тож у перекладі зберігаються початкові вкладення.

Якщо не вказати `translate` або встановити для нього значення `true`, збережеться наявна поведінка: рішення ухвалює тип поля. Це не дає змоги перекладати приховані поля або типи значень на кшталт `select`. Параметр застосовується до полів блоків і розширень, не приховує й не вимикає елементи керування редактора та не змінює збережені значення. Після зміни налаштування знову запустіть `wp bs wpml config` та оновіть `wpml-config.xml` за допомогою створеної конфігурації.

`label` кожного ключа — це назва поля, перед якою стоять назви батьківських повторювачів і груп з ідентифікатором. WPML показує її як назву поля в редакторі перекладів. Два ключі поля `link` додають до назви `Link text` і `URL`. Ці суфікси перекладаються мовою сайту, тож запускайте команду з локаллю, якою користуються ваші перекладачі.

### Власні типи полів

Тип поля, що зберігає звичайний текстовий рядок, зазначає це під час реєстрації. У визначенні встановіть для `translate` значення `true`; для цього потрібно, щоб `attribute` було `string`:

```php title="functions.php"
bs_register_field_type('acme/headline', [
  'attribute' => 'string',
  'translate' => true,
]);
```

Потім команда оголошує кожне поле цього типу текстом, що підлягає перекладу. Для окремого поля все ще можна встановити `"translate": false`, щоб виключити його. Без цього параметра поля цього типу, як і раніше, виключаються та виводяться у звіті.

### Зміна міток

Мітки полів призначені для редактора блоків і можуть містити підказки на кшталт «Зображення (необов’язково)», які не мають значення в редакторі перекладів. Фільтр `blockstudio/wpml/config/label` отримує кожну мітку перед її записом разом із контекстом ключа:

- `block`: назва блока.
- `path`: шлях зберігання поля під `blockstudio.attributes`, із рівнем `*` для рядків кожного повторювача, наприклад `cards/*/link`.
- `field`: визначення поля.
- `parents`: мітки батьківських повторювачів і груп з ID.
- `part`: `text` для текстового поля, `title` або `url` для двох ключів поля посилання.

```php title="functions.php"
add_filter('blockstudio/wpml/config/label', function ($label, $context) {
  return str_replace(' (optional)', '', $label);
}, 10, 2);
```

Поверніть порожній рядок, щоб не виводити мітку ключа; тоді WPML показуватиме мітку блока. Якщо повернене значення не є рядком, зберігається початкова мітка. Запустіть команду ще раз після зміни фільтра.

### Поля з однаковим ключем зберігання

Два поля можуть мати однаковий ключ зберігання, наприклад поле блока й поле розширення з однаковим `id` або поле `text` у групі з ID `cta` та поле з ID `cta_text`. Команда оголошує такий ключ лише тоді, коли зрозуміло, що саме там зберігається:

- Серед полів блока поза рядками повторювача Blockstudio реєструє один атрибут на ключ зберігання, тож пізніше поле замінює попереднє незалежно від типу. Так само працюють поля розширень блока: пізніше поле або поле розширення, зареєстрованого пізніше, замінює попереднє.
- Поле блока й поле розширення з однаковим ключем залишаються активними обидва. Шаблон блока отримує значення згідно з визначенням поля блока, а до розширення застосовується його власне поле. Ключ оголошується один раз, коли обом полям потрібне однакове оголошення: обидва є текстовими полями (`text`, `textarea`, `richtext` або `wysiwyg`), обидва є посиланнями, обидва є полями `files` (якщо в будь-якого з них є `multiple`, ключ отримує рівень `*`) або жодне з них не оголошується, наприклад `select` і `number`. Два повторювачі порівнюються поле за полем у своїх рядках. Мітка береться з поля блока.
- Два поля з однаковим `id` у рядках одного повторювача також залишаються активними обидва й порівнюються так само.

Якщо типи відрізняються, наприклад поле `text` у блоці та `select` у розширенні, збережене значення буде текстом або вибраним варіантом — залежно від елемента керування, який його записав. Команда не оголошує ключ і виводить попередження:

```bash
Warning: Not declared, the fields that store this key have different types: my-theme/cards: tone (text in the block, select in an extension)
```

Перейменуйте одне з полів або задайте обом однаковий тип, щоб оголосити ключ.

## Підтримуйте конфігурацію актуальною

Повторно запускайте команду після додавання, видалення чи перейменування полів і додавайте оновлений файл до теми або плагіна. Перегенеруйте конфігурації, створені до 7.7.5, щоб додати оголошення ID вкладень. Для наявного контенту нові поля стануть доступними для перекладу після оновлення оригіналу, як описано в наведеному вище посібнику WPML.

З `--file` команда створює відсутній файл. У наявному файлі вона замінює лише текст між `<!-- blockstudio:start -->` і `<!-- blockstudio:end -->`, залишаючи інші розділи та записи для інших блоків без змін:

```xml title="wpml-config.xml"
<wpml-config>
	<custom-types>
		<custom-type translate="1">book</custom-type>
	</custom-types>
	<gutenberg-blocks>
		<gutenberg-block type="my-plugin/map" translate="1">
			<key name="caption" />
		</gutenberg-block>
		<!-- blockstudio:start -->
		<!-- blockstudio:end -->
	</gutenberg-blocks>
</wpml-config>
```

Щоб використовувати наявний файл без маркерів, один раз додайте два рядки маркерів до його елемента `gutenberg-blocks` або додайте елемент `gutenberg-blocks` із маркерами, якщо такого елемента у файлі немає. Якщо маркерів немає або результат не буде коректною конфігурацією, команда не змінює файл і завершується з помилкою.

Записи для блоків Blockstudio, додані вручну, наприклад записи `translate="0"`, що приховують технічні значення, більше не потрібні, коли згенерований розділ охоплює блок. Команда попереджає про кожен блок, оголошений кілька разів, тож ці записи можна видалити.

## Тексти зображень у завданнях на переклад

WPML додає до завдання на переклад сторінки тексти зображень, які вона використовує: заголовок, альтернативний текст, підпис і опис. Після завершення завдання WPML записує перекладені тексти у вкладення цільової мови й створює його, якщо такого ще немає. Див. посібник [Як перекладати медіафайли](https://wpml.org/documentation/translating-your-contents/media/).
WPML знаходить зображення в тегах `<img>` у вмісті, галереях, головному зображенні та відомих йому блоках. Блок Blockstudio зберігає ID вкладень у коментарі блока, тому WPML їх не знаходить.

Коли активний WPML, Blockstudio додає до знайдених зображень WPML вкладення, які поля блоків сторінки зберігають:

- Поля `files`, зокрема приховані, і поля `attributes` з `media` — ті самі поля, які редактор блоків завантажує як медіафайли.
- Поля в групах, вкладках, рядках повторювачів і внутрішніх блоках.
- Поля [розширень](https://blockstudio.dev/uk/docs/extensions/), зокрема в основних блоках і блоках інших плагінів, оскільки їхні значення зберігаються в атрибутах розширеного блока.

Значення, які не є ID вкладення, виключаються. Налаштування не потрібне, а `wpml-config.xml` не використовується. Без WPML нічого не сканується для завдань на переклад, а клас інтеграції з медіафайлами не завантажується.

Це окремо від перетворення ID вкладень: згенерований XML повідомляє WPML, яке перекладене вкладення відтворювати, тоді як ця інтеграція повідомляє йому, які тексти вкладень додавати до завдання на переклад. Текстові посилання та ID дописів, що не є вкладеннями, не додаються до завдань для медіафайлів. Збережені вкладені значення полів мають пріоритет над значеннями верхнього рівня в блоках Blockstudio, як і під час відтворення.

Тексти додаються до завдання лише тоді, коли ввімкнено один із параметрів для текстів зображень у розділі WPML > Settings > Media Translation: «Automatically detect best options for translating image texts» або «Translate Media Library texts when translating content», як і для зображень в основних блоках.

Blockstudio передає зображення через фільтр
`wpml_ids_of_media_used_in_post`, який WPML застосовує до медіафайлів допису в
`PostWithMediaFiles`. Щоб виключити зображення із завдань, видаліть його ID у
зворотному виклику того самого фільтра з пріоритетом вище 10:

```php
add_filter(
	'wpml_ids_of_media_used_in_post',
	function ( $ids ) {
		return array_values( array_diff( $ids, array( 42 ) ) );
	},
	20
);
```
