Wie Florian Brinkmann aufmerksam las, wird sich das Markup des Gruppen-Blocks in WordPress 5.8 ändern, sofern eine theme.json innerhalb des Themes verwendet wird. Genauer gesagt wird der innere div mit der Klasse wp-block-group__inner-container nicht mehr Bestandteil des Gruppen-Blocks sein.

Spontan kam mir nur ein „wieso?“ in den Sinn. An sich stört der div nicht, wenn man ihn nicht benötigt, andererseits ist er für einige Layouts durchaus nützlich. Als Beispiel sei hier genannt, dass man den Gruppen-Block auf volle Breite haben möchte, beispielsweise um die gesamte Gruppe mit einer Hintergrundfarbe zu versehen, allerdings den Inhaltsbereich des Gruppen-Blocks zentriert mit einer festen Breite anzeigen möchte. Das ist ist zwar auch ohne den zusätzlichen div möglich, wird aber immer komplizierter sein. Insbesondere wenn man bei den Blöcken innerhalb der Gruppe ebenso alignwide und alignfull unterstützen möchte.

So entstand zwischen Florian und mir schnell die Idee, dass eine Lösung her musste. Aufgrund vergangener Änderungen beim Spalten-Block wussten wir auch sofort, wo wir ansetzen mussten.

Bisher sah das Markup immer so aus:

Ab WordPress 5.8 mit aktiver theme.json wird es so aussehen:

Um den hier fehlenden div mit der Klasse wp-block-group__inner-container wieder hinzuzufügen, genügt eine Funktion, die den Hook render_block_core/group verwendet:

/**
 * Add group block inner container.
 * The inner container has been removed in WordPress 5.8 if a theme.json
 * is available in the theme.
 * 
 * @param	string	$block_content The block content
 * @return	string The updated block content
 */
function my_add_block_group_inner( $block_content ) {
	libxml_use_internal_errors( true );
	$dom = new DOMDocument();
	$dom->loadHTML(
		'<html><meta charset="utf-8">' . $block_content . '</html>',
		LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD
	);
	
	foreach ( $dom->getElementsByTagName( 'div' ) as $div ) {
		// check for desired class name
		if (
			strpos( $div->getAttribute( 'class' ), 'wp-block-group' ) === false
			|| strpos( $div->getAttribute( 'class' ), 'wp-block-group__inner-container' ) !== false
		) {
			continue;
		}
		
		// check if we already processed this div
		foreach ( $div->childNodes as $childNode ) {
			if (
				method_exists( $childNode, 'getAttribute' )
				&& strpos( $childNode->getAttribute( 'class' ), 'wp-block-group__inner-container' ) !== false
			) {
				continue 2;
			}
		}
		
		// create the inner container element
		$inner_container = $dom->createElement( 'div' );
		$inner_container->setAttribute( 'class', 'wp-block-group__inner-container' );
		// get all children of the current group
		$children = iterator_to_array( $div->childNodes );
		
		// append all children to the inner container
		foreach ( $children as $child ) {
			$inner_container->appendChild( $child );
		}
		
		// append new inner container to the group block
		$div->appendChild( $inner_container );
	}
	
	return str_replace( [ '<html><meta charset="utf-8">', '</html>' ], '', $dom->saveHTML( $dom->documentElement ) );
}

add_filter( 'render_block_core/group', 'my_add_block_group_inner' );
Code-Sprache: PHP (php)

Nach Einlesen des Blocks in ein DOMDocument (weitere Informationen dazu findest du in einem vorangegangenen Blog-Beitrag von mir) prüfen wir für jeden Div, ob die entsprechende Klasse vorhanden ist (Zeile 22–28) und weiterhin, ob wir bereits unseren gewünschten Div hinzugefügt haben (Zeile 30–38).

Wenn das nicht der Fall ist, wird der innere Div erstellt, die Elemente innerhalb der Gruppe in diesen neuen inneren Div eingefügt (Zeile 48) und dann der ganze innere Div dem Gruppen-Block hinzugefügt (Zeile 52).

Damit erhält man dann am Ende wieder dasselbe Markup wie vor WordPress 5.8, auch mit vorhandener theme.json.

10 Kommentare

  1. Nach jeder Aktualisierung von WordPress sorgt Gutenberg bei mir für schlechte Laune. Dabei ist der Blockeditor grundätzlich eine gute Idee. Doch entweder werden Features hinzugefügt, die dann wieder hausgenommen werden, ändert sich das Editor-Verhalten sodass sich keine Routine einstellen will oder – wie hier – werden Grundstrukturen verändert, sodass Themes erheblich verändert werden müssen.

    SO macht Gutenberg auf keinen Fall Spaß. Danke für den guten Beitrag – damit ist zumindest mein Tag gerettet.

  2. Hier sollte besser add_filter() aufgerufen werden, oder? Leider funktioniert der Filter nicht im Backend und nicht bei verschachtelten Group Blöcken.

    1. Ich habe nun die Lösung mit einer neuen Variante ersetzt, die auch verschachtelte Gruppen-Blöcke beachtet. Danke nochmal für den Hinweis!

  3. Änderungen wie diese sind natürlich ärgerlich.

    Aber ich muss den Gutenberg-Entwicklern zugute heißen, dass sie das Problem erkannt haben, und auch eine Lösung bieten.

    Den wer die `theme.json` Datei für Styles benutzt, braucht sich um Details wie Block-Markup oder CSS-Klassennamen keine Gedanken mehr zu machen.

    Auch die Alignment-Controls in 5.8 machen Szenarien wie einen Gruppen-Block mit voller Breite, aber mit einem in der Breite begrenzten Inhalt möglich.

    1. Auch inklusive theme.json gibt es durchaus Varianten, in denen diese zusätzliche Klasse noch benötigt wird. Denn rein von der Anzeige ändert die theme.json nichts an den Möglichkeiten mit dem jeweiligen Quellcode und dann kann es zu genau denselben Problemen kommen wie ohne theme.json.

  4. I am now getting an error:

    „Deprecated: mb_convert_encoding(): Handling HTML entities via mbstring is deprecated; use htmlspecialchars, htmlentities, or mb_encode_numericentity/mb_decode_numericentity instead in /workspace/website/wp-content/themes/plaudit-theme-child/functions.php on line 203“

    How do you recommend resolving this?

    Thanks.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert