Gutenberg: Wiederverwendbare Blöcke und has_block()
Veröffentlicht: – Kommentar hinterlassen Letzte Aktualisierung:
Nutzt man wiederverwendbare Blöcke und möchte mit has_block()
prüfen, ob ein bestimmter Block innerhalb eines Beitrags verwendet wird, so werden die Inhalte wiederverwendbare Blöcke dabei ignoriert. Dadurch kann es hierbei zu „false negatives“ führen, also falsch-negative Erkennungen.
Hintergrund ist, dass has_block()
, das übrigens im WordPress Core mitgeliefert wird, den Quellcode des Beitrags verarbeitet. Soweit, so gut. Wiederverwendbare Blöcke sind innerhalb eines Beitrags jedoch nur eine Referenz auf einen ganzen Beitrag eines individuellen Inhaltstyps (wp_block
) und sieht dabei beispielsweise folgendermaßen im Quellcode aus:
<!-- wp:block {"ref":1337} /-->
Code-Sprache: HTML, XML (xml)
Dadurch erkennt has_block()
hier nur einen Block mit dem generischen Typ block
, aber nicht den eigentlichen Inhalt des wiederverwendbaren Blocks. Um dies anzupassen, sodass auch Inhalte der wiederverwendbaren Blöcke überprüft werden, muss man die Blöcke eines Beitrags zuerst selbst parsen, wiederverwendbare Blöcke innerhalb des Beitrags erkennen und über diese die Funktion has_block()
laufen lassen.
Auf GitHub konnte ich dafür einen entsprechenden Issue finden und auch einen Workaround in Form einer eigenen Funktion, die genau das tut. Diese habe ich für mich noch etwas angepasst, sodass sie nun so aussieht:
/**
* Check if a block is inside a post, even if it's a reusable one.
*
* @param string $block_name Full Block type to look for
* @param bool $id The post ID to look for
* @return bool True if the post contains this block, false otherwise
*/
function my_has_block( $block_name, $id = false ) {
$id = ( $id ?: get_the_ID() );
if ( has_block( $block_name, $id ) ) {
return true;
}
if ( ! $id ) {
return false;
}
// check reusable blocks
if ( has_block( 'block', $id ) ) {
$content = get_post_field( 'post_content', $id );
$blocks = parse_blocks( $content );
if ( ! is_array( $blocks ) || empty( $blocks ) ) {
return false;
}
foreach ( $blocks as $block ) {
if ( ! empty( $block['attrs']['ref'] ) && has_block( $block_name, $block['attrs']['ref'] ) ) {
return true;
}
if ( ! empty( $block['innerBlocks'] ) ) {
foreach ( $block['innerBlocks'] as $inner_block ) {
if ( ! empty( $inner_block['attrs']['ref'] ) && has_block( $block_name, $inner_block['attrs']['ref'] ) ) {
return true;
}
}
}
}
}
return false;
}
Code-Sprache: PHP (php)
Dabei kann er genau so verwendet werden, wie has_block()
auch, also in dem Fall beispielsweise so:my_has_block( 'audio' )
Hinweis: Diese Funktion findet so keinen wiederverwendbaren Block innerhalb eines anderen wiederverwendbaren Blocks.