Saltar al contenido

WPML

WPML traduce los atributos de un bloque personalizado solo hasta donde los declara un archivo de configuración de idioma. Blockstudio guarda cada valor de campo en el comentario del bloque bajo blockstudio.attributes, así que cada bloque necesita una entrada que indique a WPML sus campos de texto y los ID de sus adjuntos. El comando wp bs wpml config escribe estas entradas para cada bloque registrado.

Por qué los bloques necesitan una configuración

WPML lee la configuración de un archivo llamado wpml-config.xml en la carpeta raíz del tema activo y de cada plugin activo. Si un plugin de uso obligatorio consta de un solo archivo, la carpeta lleva el nombre del archivo sin .php. Consulta Archivos de configuración de idiomas y Haz que los bloques de Gutenberg sean traducibles.

Un bloque sin una entrada queda sujeto a la detección automática de cadenas de WPML, que ofrece para traducir todos los atributos de cadena del bloque. En un bloque Blockstudio que incluye valores de selección, referencias a archivos, URL y clases CSS. Los traductores ven estos valores técnicos junto al texto real, y traducir un valor de selección o una clase puede romper el bloque.

Generar la configuración

Imprime la configuración y guárdala en la carpeta raíz del tema o plugin que incluye los bloques:

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

O deja que el comando escriba el archivo:

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

Un bloque con un campo de texto, una imagen, un enlace y un repetidor:

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" }
        ]
      }
    ]
  }
}

se convierte en:

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>

El valor style no está declarado, así que WPML lo copia sin cambios a la traducción. También se copian los IDs de gallery y image, y WPML sustituye cada uno por el adjunto correspondiente al idioma de la página al renderizar el bloque, de modo que una imagen traducida puede tener su propio texto alternativo. Consulta «Convertir IDs automáticamente en bloques» en Haz que los bloques de Gutenberg sean traducibles. Si un adjunto no tiene traducción, WPML conserva el ID original.

Qué se declara

El comando lee los bloques registrados después de expandir los campos de custom/ y los campos del bloque, y de aplicar las anulaciones y los filtros de atributos. Se incluyen los campos que las extensiones añaden a un bloque de Blockstudio. No se incluyen los campos que las extensiones añaden a los bloques del núcleo o a los de otros plugins, porque esos bloques obtienen su configuración de WPML o de su propio plugin.

Campo Declaración
text, textarea, richtext, wysiwyg Texto traducible.
link title como texto y url con type="link", para que WPML sustituya un enlace por su traducción cuando esté disponible.
files El ID del adjunto guardado con type="post-ids" y sub-type="attachment". Con multiple, un nivel llamado * para la lista, que también coincide con el ID único que guarda el campo cuando se selecciona un solo archivo.
repeater Un nivel llamado * que coincide con cada fila, con las declaraciones de los campos de la fila. Los repetidores anidados funcionan igual.
group con un id Los campos del grupo, con el ID del grupo como prefijo de clave (cta_text para el campo text del grupo cta).
group sin un id, tabs Los campos, sin un nivel propio.
Tipo de campo personalizado registrado con translate establecido en true Texto traducible, como un campo text.
Cualquier otro tipo integrado No se declara. WPML copia el valor sin cambios.

Un bloque sin ningún campo de texto declarado obtiene translate="0". Después, WPML copia todos sus valores y no ofrece ninguno para traducir. Sus campos files siguen declarados dentro de la entrada, porque WPML convierte los IDs de adjuntos independientemente de lo que indique translate. Los bloques internos se traducen como siempre.

No se declaran:

  • Campos con hidden, porque los editores no escriben sus valores.
  • Campos con "translate": false; consulta más abajo.
  • Campos de tipos de campos personalizados que no están registrados con translate establecido en true. El comando muestra una advertencia para cada uno, porque solo el tipo de campo sabe si su valor contiene texto. Una "translate": false explícita en un campo también suprime la advertencia para ese campo. Consulta más abajo.
  • Atributos que un bloque declara en su attributes nativo, en lugar de hacerlo como campos Blockstudio.
  • Claves de almacenamiento cuyos campos tienen tipos diferentes; consulta más abajo.

Se declara todo campo de texto, incluso los que contienen un valor técnico, como una clase CSS, salvo que establezca "translate": false.

Omitir un campo

Un campo de texto puede contener un valor que debe ser igual en todos los idiomas: un nombre de usuario, una dirección de correo electrónico, un ancla o una clase CSS. WPML lo ofrece para traducir igual que cualquier otro texto, y un valor traducido puede romper el bloque. Establece translate en false para omitir el campo de la configuración, de modo que WPML copie su valor sin cambios a la traducción:

JSON
{
  "id": "account",
  "type": "text",
  "label": "Account handle",
  "translate": false
}

En un group, tabs o repeater, "translate": false se aplica a todos los campos internos, incluidos los contenedores anidados. Un elemento secundario no puede anular un contenedor excluido con "translate": true. En un campo files, false también omite los IDs de los adjuntos, por lo que la traducción conserva los adjuntos originales.

Si se omite translate o se establece en true, se conserva el comportamiento existente: decide el tipo de campo. Esto no hace que los campos ocultos ni los tipos de valor como select sean traducibles. La opción se aplica a los campos de bloques y extensiones, no oculta ni desactiva sus controles en el editor y no cambia los valores guardados. Vuelve a ejecutar wp bs wpml config después de cambiar la configuración y actualiza tu wpml-config.xml con la configuración generada.

El label de cada clave es la etiqueta del campo, precedida por las etiquetas de los repetidores y grupos contenedores que tienen un ID. WPML la muestra como nombre del campo en el editor de traducción. Las dos claves de un campo link añaden Link text y URL a la etiqueta. Estos sufijos se traducen al idioma del sitio, así que ejecuta el comando con la configuración regional que usan tus traductores.

Tipos de campos personalizados

Un tipo de campo que guarda una cadena de texto simple lo indica al registrarse. En la definición, establece translate en true, lo que requiere que attribute sea string:

PHP
bs_register_field_type('acme/headline', [
  'attribute' => 'string',
  'translate' => true,
]);

A continuación, el comando declara traducible como texto cada campo de ese tipo. Un campo aún puede establecer "translate": false para excluirse. Sin esa opción, los campos del tipo se excluyen y se notifican, como antes.

Cambiar las etiquetas

Las etiquetas de los campos se escriben para el editor de bloques y pueden incluir indicaciones como «Imagen (opcional)» que no tienen sentido en el editor de traducción. El filtro blockstudio/wpml/config/label recibe cada etiqueta antes de escribirla, junto con el contexto de la clave:

  • block: el nombre del bloque.
  • path: la ruta de almacenamiento del campo debajo de blockstudio.attributes, con un nivel * para las filas de cada repetidor, por ejemplo cards/*/link.
  • field: la definición del campo.
  • parents: las etiquetas de los repetidores y grupos contenedores que tienen un ID.
  • part: text para un campo de texto, title o url para las dos claves de un campo de enlace.
PHP
add_filter('blockstudio/wpml/config/label', function ($label, $context) {
  return str_replace(' (optional)', '', $label);
}, 10, 2);

Devuelva una cadena vacía para excluir la etiqueta de una clave; así, WPML muestra en su lugar la etiqueta del bloque. Un valor devuelto que no sea una cadena conserva la etiqueta original. Vuelva a ejecutar el comando después de cambiar el filtro.

Campos con la misma clave de almacenamiento

Dos campos pueden acabar con la misma clave de almacenamiento; por ejemplo, un campo de bloque y un campo de extensión con el mismo id, o el campo text de un grupo con el ID cta y un campo con el ID cta_text. El comando declara esa clave solo cuando está claro qué se almacena en ella:

  • Entre los campos de un bloque, fuera de las filas de repetidores, Blockstudio registra un atributo por cada clave de almacenamiento, por lo que un campo posterior reemplaza a uno anterior, sea cual sea su tipo. Los campos de las extensiones de un bloque funcionan del mismo modo: un campo posterior, o el campo de una extensión registrada más tarde, reemplaza a uno anterior.
  • Un campo de bloque y un campo de extensión con la misma clave siguen teniendo efecto. La plantilla del bloque recibe el valor tal como lo define el campo del bloque, mientras que la extensión se aplica con su propio campo. La clave se declara una sola vez cuando ambos campos necesitan la misma declaración: ambos son campos de texto (text, textarea, richtext o wysiwyg), ambos son enlaces, ambos son campos files (con multiple en cualquiera de ellos, la clave obtiene el nivel *) o ninguno está declarado, como en el caso de un select y un number. Los repetidores se comparan campo por campo en sus filas. La etiqueta procede del campo del bloque.
  • Dos campos con el mismo id en las filas de un repetidor también siguen teniendo efecto y se comparan del mismo modo.

Cuando los tipos difieren, por ejemplo, un campo text en el bloque y uno select en una extensión, el valor almacenado es texto o una opción de selección, según el control que lo haya escrito. El comando no declara la clave y muestra una advertencia:

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

Cambie el nombre de uno de los campos o asígneles el mismo tipo para que se declare la clave.

Mantener la configuración al día

Vuelva a ejecutar el comando después de añadir, quitar o cambiar el nombre de campos, y distribuya el archivo actualizado con el tema o el plugin. Vuelva a generar las configuraciones creadas antes de 7.7.5 para incluir las declaraciones de ID de adjunto. El contenido creado anteriormente mostrará los campos nuevos para traducir una vez que se actualice su original, como se explica en la guía WPML anterior.

Con --file, el comando crea el archivo si no existe. Si ya existe, solo reemplaza el texto entre <!-- blockstudio:start --> y <!-- blockstudio:end -->, por lo que las demás secciones y las entradas de otros bloques permanecen intactas:

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>

Para usar un archivo existente que aún no tenga marcadores, añada una vez las dos líneas de marcadores dentro de su elemento gutenberg-blocks, o añada un elemento gutenberg-blocks con los marcadores si el archivo no contiene ninguno. Sin los marcadores, o si el resultado no fuera una configuración válida, el comando deja el archivo sin cambios y termina con un error.

Las entradas de bloques Blockstudio escritas a mano, como las entradas translate="0" que ocultan valores técnicos, ya no son necesarias cuando la sección generada cubre el bloque. El comando advierte sobre cada bloque declarado más de una vez, para que se puedan eliminar esas entradas.

Textos de imágenes en trabajos de traducción

WPML añade al trabajo de traducción de una página los textos de las imágenes que esta utiliza: título, texto alternativo, leyenda y descripción. Al completar el trabajo, WPML escribe los textos traducidos en el adjunto del idioma de destino y crea ese adjunto si aún no existe. Consulte Cómo traducir medios. WPML busca las imágenes en las etiquetas <img> del contenido, en galerías, en la imagen destacada y en los bloques que reconoce. Un bloque Blockstudio almacena los ID de adjunto en el comentario del bloque, por lo que WPML no encuentra ninguno de ellos.

Cuando WPML está activo, Blockstudio añade a las imágenes encontradas WPML los adjuntos que almacenan sus campos en los bloques de una página:

  • Campos files, incluidos los ocultos, y campos attributes con media, los mismos campos que el editor de bloques carga como medios.
  • Campos en grupos, pestañas, filas de repetidores y bloques internos.
  • Campos de extensiones, también en bloques del núcleo y de otros plugins, porque sus valores se almacenan en los atributos del bloque ampliado.

Se excluyen los valores que no sean el ID de un adjunto. No es necesario configurar nada y wpml-config.xml no interviene. Sin WPML, no se analiza nada para los trabajos de traducción y no se carga la clase de integración de medios.

Esto es independiente de la conversión de ID de adjunto: el XML generado indica a WPML qué adjunto traducido debe mostrar, mientras que esta integración le indica qué textos de adjuntos incluir en un trabajo de traducción. Las referencias a cadenas y los ID de publicaciones que no sean adjuntos no se añaden a los trabajos de medios. En los bloques Blockstudio, los valores guardados de campos anidados tienen prioridad sobre los valores de nivel superior, igual que al mostrarlos.

Los textos solo forman parte del trabajo si está activada alguna de las opciones de texto de imágenes en WPML > Settings > Media Translation: «Detectar automáticamente las mejores opciones para traducir textos de imágenes» o «Traducir los textos de la biblioteca de medios al traducir contenido», igual que para las imágenes de los bloques del núcleo.

Blockstudio informa de las imágenes mediante el filtro wpml_ids_of_media_used_in_post, que WPML se aplica a los medios de una entrada en PostWithMediaFiles. Para excluir una imagen de los trabajos, elimine su ID en una función de retorno de llamada del mismo filtro con una prioridad superior a 10:

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