Zum Inhalt springen

WPML

WPML übersetzt die Attribute eines benutzerdefinierten Blocks nur so weit, wie es eine Sprachkonfigurationsdatei festlegt. Blockstudio speichert jeden Feldwert im Blockkommentar unter blockstudio.attributes. Deshalb benötigt jeder Block einen Eintrag, der WPML auf seine Textfelder und Anhang-IDs verweist. Der Befehl wp bs wpml config erstellt diese Einträge für jeden registrierten Block.

Warum Blöcke eine Konfiguration benötigen

WPML liest die Konfiguration aus einer Datei namens wpml-config.xml im Stammordner des aktiven Themes und jedes aktiven Plugins. Bei einem Must-use-Plugin, das aus einer einzelnen Datei besteht, trägt der Ordner den Namen der Datei ohne .php. Siehe Sprachkonfigurationsdateien und Eigene Gutenberg Blocks übersetzbar machen.

Ein Block ohne Eintrag wird der automatischen String-Erkennung von WPML überlassen, die jedes String-Attribut des Blocks zur Übersetzung anbietet. Bei einem Blockstudio-Block gehören dazu Auswahlwerte, Dateiverweise, URLs und CSS-Klassen. Übersetzer sehen diese technischen Werte neben dem eigentlichen Text, und ein übersetzter Auswahlwert oder eine übersetzte Klasse kann den Block beschädigen.

Konfiguration generieren

Gib die Konfiguration aus und speichere sie im Stammordner des Themes oder Plugins, das die Blöcke bereitstellt:

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

Oder lass den Befehl die Datei schreiben:

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

Ein Block mit einem Textfeld, einem Bild, einem Link und einem Repeater:

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

wird zu:

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>

Der Wert style ist nicht deklariert, deshalb kopiert WPML ihn unverändert in die Übersetzung. Auch die IDs gallery und image werden kopiert, und WPML ersetzt jede davon beim Rendern des Blocks durch den Anhang der Seitensprache, sodass ein übersetztes Bild einen eigenen Alternativtext haben kann. Siehe „IDs in Blöcken automatisch konvertieren“ in Eigene Gutenberg Blocks übersetzbar machen. Wenn ein Anhang keine Übersetzung hat, behält WPML die ursprüngliche ID bei.

Was deklariert wird

Der Befehl liest die registrierten Blöcke, nachdem custom/-Felder und Blockfelder erweitert und Überschreibungen sowie Attributfilter angewendet wurden. Felder, die Erweiterungen zu einem Blockstudio-Block hinzufügen, werden einbezogen. Felder, die Erweiterungen zu Core-Blöcken oder Blöcken anderer Plugins hinzufügen, dagegen nicht, da diese Blöcke ihre Konfiguration von WPML oder ihrem eigenen Plugin erhalten.

Feld Deklaration
text, textarea, richtext, wysiwyg Übersetzbarer Text.
link title als Text und url mit type="link", sodass WPML einen Link durch seine Übersetzung ersetzt, sofern eine verfügbar ist.
files Die gespeicherte Anhang-ID mit type="post-ids" und sub-type="attachment". Mit multiple eine Ebene namens * für die Liste, die auch zur einzelnen ID passt, die das Feld speichert, wenn eine Datei ausgewählt ist.
repeater Eine Ebene namens *, die zu jeder Zeile passt, mit den Deklarationen der Zeilenfelder. Verschachtelte Repeater funktionieren genauso.
group mit einem id Die Felder der Gruppe, wobei die Gruppen-ID als Schlüsselpräfix dient (cta_text für das Feld text in der Gruppe cta).
group ohne ein id, tabs Die Felder ohne eigene Ebene.
Benutzerdefinierter Feldtyp, registriert mit translate auf true gesetzt Übersetzbarer Text, wie bei einem text-Feld.
Jeder andere integrierte Typ Nicht deklariert. WPML kopiert den Wert unverändert.

Ein Block ohne deklariertes Textfeld erhält translate="0". WPML kopiert dann alle Werte des Blocks und bietet nichts davon zur Übersetzung an. Seine files-Felder werden weiterhin im Eintrag deklariert, weil WPML Anhang-IDs unabhängig davon konvertiert, was translate vorgibt. Innere Blöcke werden wie gewohnt übersetzt.

Nicht deklariert:

  • Felder mit hidden, da ihre Werte nicht von Redakteuren geschrieben werden.
  • Felder mit "translate": false, siehe unten.
  • Felder benutzerdefinierter Feldtypen, die nicht mit translate auf true registriert sind. Der Befehl gibt für jedes Feld eine Warnung aus, da nur der Feldtyp weiß, ob sein Wert Text enthält. Ein explizites "translate": false für ein Feld unterdrückt diese Warnung ebenfalls. Siehe unten.
  • Attribute, die ein Block in seinem nativen attributes statt als Blockstudio-Felder deklariert.
  • Speicherschlüssel, deren Felder unterschiedliche Typen haben, siehe unten.

Jedes Textfeld wird deklariert, auch eines, das einen technischen Wert wie eine CSS-Klasse enthält, sofern es nicht "translate": false festlegt.

Feld ausschließen

Ein Textfeld kann einen Wert enthalten, der in jeder Sprache gleich bleiben muss: einen Accountnamen, eine E-Mail-Adresse, einen Anker oder eine CSS-Klasse. WPML bietet ihn wie jeden anderen Text zur Übersetzung an, und ein übersetzter Wert kann den Block beschädigen. Setze translate auf false, um das Feld aus der Konfiguration auszuschließen, sodass WPML seinen Wert unverändert in die Übersetzung kopiert:

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

Bei einem group, tabs oder repeater gilt "translate": false für jedes enthaltene Feld, auch in verschachtelten Containern. Ein Kindelement kann einen ausgeschlossenen Container nicht mit "translate": true überschreiben. Bei einem files-Feld schließt false auch die Anhang-IDs aus, sodass die Übersetzung die ursprünglichen Anhänge beibehält.

Wenn du translate weglässt oder auf true setzt, bleibt das bisherige Verhalten erhalten: Der Feldtyp entscheidet. Dadurch werden weder verborgene Felder noch Werttypen wie select übersetzbar. Die Option gilt für Block- und Erweiterungsfelder, blendet deren Steuerelemente im Editor nicht aus und deaktiviert sie nicht und ändert auch ihre gespeicherten Werte nicht. Führe wp bs wpml config nach einer Änderung der Einstellung erneut aus und aktualisiere dein wpml-config.xml mit der generierten Konfiguration.

Der label jedes Schlüssels ist die Feldbeschriftung, der die Beschriftungen der umschließenden Repeater und Gruppen mit einer ID vorangestellt werden. WPML zeigt sie im Übersetzungseditor als Feldnamen an. Die beiden Schlüssel eines link-Felds ergänzen die Beschriftung um Link text und URL. Diese Suffixe werden in die Sprache der Website übersetzt. Führe den Befehl daher mit der Locale aus, in der deine Übersetzer arbeiten.

Benutzerdefinierte Feldtypen

Ein Feldtyp, der eine einfache Textzeichenfolge speichert, gibt dies bei seiner Registrierung an. Setze translate in der Definition auf true. Dafür muss attribute auf string gesetzt sein:

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

Der Befehl deklariert dann jedes Feld dieses Typs als übersetzbaren Text. Ein Feld kann weiterhin "translate": false setzen, um sich selbst auszuschließen. Ohne die Option werden die Felder dieses Typs wie zuvor ausgeschlossen und gemeldet.

Beschriftungen ändern

Feldbeschriftungen sind für den Block-Editor gedacht und können Hinweise wie „Bild (optional)“ enthalten, die im Übersetzungseditor keine Bedeutung haben. Der Filter blockstudio/wpml/config/label erhält jede Beschriftung vor dem Schreiben zusammen mit dem Schlüsselkontext:

  • block: der Blockname.
  • path: der Speicherpfad des Feldes unter blockstudio.attributes, mit einer Ebene * für die Zeilen jedes Repeaters, zum Beispiel cards/*/link.
  • field: die Felddefinition.
  • parents: die Beschriftungen der übergeordneten Repeater und Gruppen mit einer ID.
  • part: text für ein Textfeld, title oder url für die beiden Schlüssel eines Linkfeldes.
PHP
add_filter('blockstudio/wpml/config/label', function ($label, $context) {
  return str_replace(' (optional)', '', $label);
}, 10, 2);

Gib eine leere Zeichenfolge zurück, um die Beschriftung eines Schlüssels auszuschließen, damit WPML stattdessen die Beschriftung des Blocks anzeigt. Ein Rückgabewert, der keine Zeichenfolge ist, lässt die ursprüngliche Beschriftung bestehen. Führe den Befehl nach einer Änderung des Filters erneut aus.

Felder mit demselben Speicherschlüssel

Zwei Felder können denselben Speicherschlüssel haben, zum Beispiel ein Blockfeld und ein Erweiterungsfeld mit demselben id oder das Feld text in einer Gruppe mit der ID cta und ein Feld mit der ID cta_text. Der Befehl deklariert einen solchen Schlüssel nur, wenn eindeutig ist, was dort gespeichert wird:

  • Innerhalb der Felder eines Blocks, außerhalb von Repeater-Zeilen, registriert Blockstudio ein Attribut pro Speicherschlüssel. Ein späteres Feld ersetzt daher ein früheres, unabhängig vom Typ. Bei den Erweiterungen eines Blocks gilt dasselbe: Ein späteres Feld oder das Feld einer später registrierten Erweiterung ersetzt ein früheres.
  • Ein Blockfeld und ein Erweiterungsfeld mit demselben Schlüssel bleiben beide wirksam. Die Blockvorlage erhält den Wert so, wie ihn das Blockfeld definiert, während die Erweiterung mit ihrem eigenen Feld angewendet wird. Der Schlüssel wird einmal deklariert, wenn beide Felder dieselbe Deklaration benötigen: Beide sind Textfelder (text, textarea, richtext oder wysiwyg), beide sind Links, beide sind files-Felder (mit multiple bei einem der beiden erhält der Schlüssel die Ebene *) oder keines ist deklariert, etwa ein select und ein number. Zwei Repeater werden Feld für Feld in ihren Zeilen verglichen. Die Beschriftung stammt vom Blockfeld.
  • Auch zwei Felder mit demselben id in den Zeilen eines Repeaters bleiben beide wirksam und werden auf dieselbe Weise verglichen.

Wenn die Typen unterschiedlich sind, zum Beispiel ein text-Feld im Block und ein select-Feld in einer Erweiterung, ist der gespeicherte Wert je nach dem Steuerelement, das ihn geschrieben hat, Text oder eine Auswahloption. Der Befehl deklariert den Schlüssel nicht und gibt eine Warnung aus:

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)

Benenne eines der Felder um oder gib beiden denselben Typ, damit der Schlüssel deklariert wird.

Konfiguration aktuell halten

Führe den Befehl erneut aus, nachdem du Felder hinzugefügt, entfernt oder umbenannt hast, und liefere die aktualisierte Datei mit dem Theme oder Plugin aus. Erzeuge Konfigurationen neu, die vor 7.7.5 erstellt wurden, damit sie Deklarationen für Attachment-IDs enthalten. Inhalte, die bereits vorhanden waren, zeigen neue Felder erst dann zur Übersetzung an, wenn ihr Original aktualisiert wurde, wie oben im WPML-Leitfaden beschrieben.

Mit --file erstellt der Befehl eine fehlende Datei. In einer vorhandenen Datei ersetzt er nur den Text zwischen <!-- blockstudio:start --> und <!-- blockstudio:end -->, sodass andere Abschnitte und Einträge für andere Blöcke unverändert bleiben:

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>

Um eine vorhandene Datei zu verwenden, die noch keine Markierungen enthält, füge die beiden Markierungszeilen einmal in ihr Element gutenberg-blocks ein oder füge ein Element gutenberg-blocks mit den Markierungen hinzu, falls die Datei keines enthält. Fehlen die Markierungen oder wäre das Ergebnis keine gültige Konfiguration, lässt der Befehl die Datei unverändert und wird mit einem Fehler beendet.

Einträge für Blockstudio-Blöcke, die von Hand geschrieben wurden, etwa translate="0"-Einträge zum Ausblenden technischer Werte, sind nicht mehr nötig, sobald der generierte Abschnitt den Block abdeckt. Der Befehl warnt vor jedem Block, der mehrfach deklariert ist, sodass du diese Einträge entfernen kannst.

Bildtexte in Übersetzungsaufträgen

WPML fügt die Texte der Bilder einer Seite zum Übersetzungsauftrag der Seite hinzu: Titel, Alternativtext, Bildunterschrift und Beschreibung. Nach Abschluss des Auftrags schreibt WPML die übersetzten Texte in den Anhang der Zielsprache und erstellt diesen Anhang, falls noch keiner vorhanden ist. Weitere Informationen findest du unter Medien übersetzen. WPML findet Bilder in <img>-Tags im Inhalt, in Galerien, im Beitragsbild und in den Blöcken, die es kennt. Ein Blockstudio-Block speichert Attachment-IDs im Blockkommentar, daher findet WPML keine davon.

Wenn WPML aktiv ist, fügt Blockstudio die Anhänge hinzu, die seine Felder in den Blöcken einer Seite speichern, und ergänzt damit die gefundenen Bilder WPML:

  • files-Felder, auch ausgeblendete, und attributes-Felder mit media – dieselben Felder, die der Block-Editor als Medien lädt.
  • Felder in Gruppen, Tabs, Repeater-Zeilen und inneren Blöcken.
  • Felder von Erweiterungen, auch bei Core-Blöcken und Blöcken anderer Plugins, da ihre Werte in den Attributen des erweiterten Blocks gespeichert sind.

Werte, die keine Attachment-ID sind, werden ausgeschlossen. Es ist keine Konfiguration erforderlich, und wpml-config.xml ist nicht beteiligt. Ohne WPML wird nichts für Übersetzungsaufträge durchsucht und die Medienintegrationsklasse nicht geladen.

Dies ist unabhängig von der Konvertierung von Attachment-IDs: Das generierte XML teilt WPML mit, welches übersetzte Attachment gerendert werden soll, während diese Integration angibt, welche Attachment-Texte in einen Übersetzungsauftrag aufgenommen werden. Zeichenfolgenverweise und IDs von Beiträgen, die keine Anhänge sind, werden nicht zu Medienaufträgen hinzugefügt. Gespeicherte verschachtelte Feldwerte haben bei Blockstudio-Blöcken Vorrang vor Werten auf oberster Ebene, wie beim Rendern.

Die Texte sind nur dann Teil des Auftrags, wenn eine der Optionen für Bildtexte unter WPML > Einstellungen > Medienübersetzung aktiviert ist: „Beste Optionen für die Übersetzung von Bildtexten automatisch erkennen“ oder „Texte der Mediathek beim Übersetzen von Inhalten übersetzen“, wie bei Bildern in Core-Blöcken.

Blockstudio meldet die Bilder über den Filter wpml_ids_of_media_used_in_post, der auf die Medien eines Beitrags in WPML angewendet wird. Um ein Bild von den Aufträgen auszuschließen, entferne seine ID in einem Callback für denselben Filter mit einer Priorität über 10: PostWithMediaFiles

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