Перейти к содержимому

WPML

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

Зачем блокам нужна конфигурация

WPML считывает конфигурацию из файла с именем wpml-config.xml в корневой папке активной темы и каждого активного плагина. Для обязательного плагина, состоящего из одного файла, папка называется так же, как файл, но без .php. См. Файлы конфигурации языков и Сделайте блоки Gutenberg переводимыми.

Блок без записи обрабатывается автоматическим определением строк в WPML, которое предлагает для перевода каждый строковый атрибут блока. Для блока Blockstudio, содержащего значения списков выбора, ссылки на файлы, URL и классы CSS. Переводчики видят эти технические значения рядом с обычным текстом, а перевод значения списка выбора или класса может нарушить работу блока.

Создание конфигурации

Выведите конфигурацию и сохраните её в корневой папке темы или плагина, содержащего блоки:

Командная оболочка
wp bs wpml config > wp-content/themes/my-theme/wpml-config.xml

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

Командная оболочка
wp bs wpml config --file=wp-content/themes/my-theme/wpml-config.xml

Блок с текстовым полем, изображением, ссылкой и повторителем:

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
<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 переводимыми. Если у вложения нет перевода, WPML сохраняет исходный идентификатор.

Что объявляется

Команда считывает зарегистрированные блоки после раскрытия полей custom/ и полей блоков, а также применения переопределений и фильтров атрибутов. Включаются поля, которые расширения добавляют в блок 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; см. ниже.
  • Поля пользовательских типов, не зарегистрированные с translate, установленным в true. Команда выводит предупреждение для каждого такого поля, поскольку только тип поля позволяет определить, содержит ли его значение текст. Явное "translate": false для поля также отключает это предупреждение. См. ниже.
  • Атрибуты, объявленные блоком в его встроенном attributes, а не в виде полей Blockstudio.
  • Ключи хранилища, поля которых имеют разные типы; см. ниже.

Объявляется каждое текстовое поле, в том числе поле с техническим значением, например классом CSS, если только в нём не задано "translate": false.

Исключение поля

Текстовое поле может содержать значение, которое должно быть одинаковым для всех языков: имя учётной записи, адрес электронной почты, якорь или класс CSS. WPML предлагает его для перевода, как любой другой текст, а перевод может нарушить работу блока. Установите для translate значение false, чтобы исключить поле из конфигурации и сохранить его значение в переводе без изменений с помощью WPML:

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
bs_register_field_type('acme/headline', [
  'attribute' => 'string',
  'translate' => true,
]);

Затем команда объявляет переводимым текстом каждое поле этого типа. Поле всё ещё может задать "translate": false, чтобы исключить себя. Без этого параметра поля этого типа, как и прежде, исключаются и выводятся в отчёте.

Изменение меток

Метки полей предназначены для редактора блоков и могут содержать подсказки вроде «Изображение (необязательно)», которые не имеют смысла в редакторе переводов. Фильтр blockstudio/wpml/config/label получает каждую метку перед её записью вместе с контекстом ключа:

  • block: имя блока.
  • path: путь хранения поля под blockstudio.attributes с уровнем * для строк каждого повторителя, например cards/*/link.
  • field: определение поля.
  • parents: метки внешних повторителей и групп с идентификатором.
  • part: text для текстового поля, title или url для двух ключей поля ссылки.
PHP
add_filter('blockstudio/wpml/config/label', function ($label, $context) {
  return str_replace(' (optional)', '', $label);
}, 10, 2);

Верните пустую строку, чтобы исключить метку ключа: тогда WPML покажет метку блока. Возвращаемое значение, не являющееся строкой, сохраняет исходную метку. После изменения фильтра запустите команду повторно.

Поля с одинаковым ключом хранения

У двух полей может оказаться одинаковый ключ хранения, например у поля блока и поля расширения с одинаковым id или у поля text в группе с идентификатором cta и поля с идентификатором cta_text. Команда объявляет такой ключ, только если ясно, какие данные в нём хранятся:

  • Среди полей блока вне строк повторителя Blockstudio регистрирует один атрибут для каждого ключа хранения. Поэтому более позднее поле заменяет более раннее независимо от типа. Для полей расширений блока действует то же правило: более позднее поле или поле расширения, зарегистрированного позже, заменяет более раннее.
  • Поле блока и поле расширения с одинаковым ключом продолжают действовать оба. Шаблон блока получает значение в соответствии с определением поля блока, а расширение применяет собственное поле. Ключ объявляется один раз, если обоим полям нужно одно и то же объявление: оба являются текстовыми полями (text, textarea, richtext или wysiwyg), оба являются ссылками, оба являются полями files (если у любого из них указано multiple, ключ получает уровень *) либо ни одно не объявляется, например select и number. Два повторителя сравниваются по полям в каждой строке. Метка берётся из поля блока.
  • Два поля с одинаковым id в строках одного повторителя тоже продолжают действовать оба и сравниваются по тому же правилу.

Если типы различаются, например text — это поле блока, а select — поле расширения, сохранённым значением может быть текст или вариант выбора — в зависимости от элемента управления, который его записал. Команда не объявляет ключ и выводит предупреждение:

Командная оболочка
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, чтобы включить объявления идентификаторов вложений. Как описано в приведённом выше руководстве WPML, в ранее созданном контенте новые поля становятся доступны для перевода после обновления исходной версии.

С параметром --file команда создаёт отсутствующий файл. В существующем файле она заменяет только текст между <!-- blockstudio:start --> и <!-- blockstudio:end -->, поэтому остальные разделы и записи для других блоков остаются без изменений:

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 записывает переведённые тексты во вложение для целевого языка и создаёт его, если вложения ещё нет. См. руководство Как переводить медиа. WPML находит изображения в тегах <img> в контенте, галереях, главном изображении и известных ему блоках. Блок Blockstudio хранит идентификаторы вложений в комментарии блока, поэтому WPML их не находит.

Когда активен WPML, Blockstudio добавляет вложения, хранящиеся в полях блоков страницы, к найденным изображениям WPML:

  • Поля files, включая скрытые, и поля attributes с media — те же поля, которые редактор блоков загружает как медиафайлы.
  • Поля в группах, вкладках, строках повторителей и внутренних блоках.
  • Поля расширений, в том числе в основных блоках и блоках других плагинов, поскольку их значения хранятся в атрибутах расширяемого блока.

Значения, не являющиеся идентификаторами вложений, исключаются. Ничего настраивать не нужно, и wpml-config.xml не задействуется. Без WPML сканирование для заданий на перевод не выполняется, а класс интеграции с медиафайлами не загружается.

Это работает отдельно от преобразования идентификаторов вложений: сгенерированный XML указывает WPML, какое переведённое вложение отображать, а эта интеграция сообщает ему, какие тексты вложений включать в задание на перевод. Строковые ссылки и идентификаторы записей, не являющихся вложениями, не добавляются в задания для медиафайлов. Сохранённые значения вложенных полей имеют приоритет перед значениями верхнего уровня в блоках Blockstudio, как и при отображении.

Тексты включаются в задание, только если в разделе WPML > Settings > Media Translation включён один из параметров перевода текстов изображений: «Автоматически подбирать оптимальные параметры для перевода текстов изображений» или «Переводить тексты из медиатеки при переводе контента» — как и для изображений в основных блоках.

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