Inhaltstyp-Archiv im Navigationsblock verwenden
Veröffentlicht: – Kommentar hinterlassen Letzte Aktualisierung:
Aktuell kannst du keine Inhaltstyp-Archive zum Navigationsblock hinzufügen. Zumindest nicht auf eine Art und Weise, dass dieser den Status erkennt, beispielsweise ob es der aktuell aktive Menüpunkt ist. Das ist ein seit Mai 2021 bekanntes Problem im Gutenberg-Projekt (siehe GitHub). Und leider sieht es nicht danach aus, als wenn es bald angepasst wird.
Als ich diese Funktionalität aber für ein individuelles Inhaltstyp-Archiv „job“ benötigte, kam ich auf eine Lösung, die die Ausgabe des Navigationsblocks verändert. Dies wird nur benötigt, um die korrekten Klassen current-menu-item und current-menu-ancestor zu setzen.
Das Skript prüft praktisch, ob die aktuelle Anfrage das Inhaltsarchiv oder eine Einzelseite des gewünschten Inhaltstyps betrifft und fügt dann die richtige Klasse zum Menüeintrag über PHPs DOMDocument hinzu. Hierbei verlass ich mich explizit auf die URL des Menüeintrags, in meinem Fall ist das /job/.
Für einen einzelnen Inhaltstypen sieht der Code demnach so aus:
/**
* Set job archive menu item as active if needed.
*
* Currently, post type archives cannot be added to the navigation block.
*
* @see https://github.com/WordPress/gutenberg/issues/31452
*
* @param string $block_content Block content
* @return string Updated block content
*/
static function my_set_job_archive_active( string $block_content ): string {
if ( ! \is_post_type_archive( 'job' ) && ! \is_singular( 'job' ) ) {
return $block_content;
}
$libxml_use_errors = \libxml_use_internal_errors( true );
$dom = new \DOMDocument();
$dom->loadHTML(
'<html><meta charset="utf-8">' . $block_content . '</html>',
LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD
);
$has_changed = false;
/** @var \DOMElement $list_element */
foreach ( $dom->getElementsByTagName( 'li' ) as $list_element ) {
$class_name = '';
// get classes of first link
foreach ( $list_element->getElementsByTagName( 'a' ) as $child_link ) {
$class_name = $child_link->getAttribute( 'class' );
break;
}
// current item already has desired class
if (
\str_contains( $class_name, 'current-menu-item' )
|| \str_contains( $class_name, 'current-menu-ancestor' )
) {
continue;
}
if ( \str_contains( $list_element->getAttribute( 'class' ), 'has-child' ) ) {
$is_target = false;
// check if a child is active
foreach ( $list_element->getElementsByTagName( 'a' ) as $child_link ) {
if ( \str_ends_with( $child_link->getAttribute( 'href' ), '/job/' ) ) {
$is_target = true;
}
}
if ( $is_target ) {
foreach ( $list_element->getElementsByTagName( 'a' ) as $link ) {
$link->setAttribute( 'class', \trim( $link->getAttribute( 'class' ) . ' current-menu-ancestor' ) );
$has_changed = true;
// only check the first item
break;
}
}
}
else {
foreach ( $list_element->getElementsByTagName( 'a' ) as $link ) {
if ( \str_ends_with( $link->getAttribute( 'href' ), '/job/' ) ) {
$new_class = 'current-menu-' . ( \is_singular( 'job' ) ? 'ancestor' : 'item' );
$list_element->setAttribute( 'class', \trim( $list_element->getAttribute( 'class' ) . ' ' . $new_class ) );
$has_changed = true;
}
// only check the first item
break;
}
}
}
if ( $has_changed ) {
$block_content = $dom->saveHTML( $dom->documentElement->firstChild->nextSibling ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
}
\libxml_use_internal_errors( $libxml_use_errors );
return $block_content;
}
\add_filter( 'render_block_core/navigation', 'my_set_job_archive_active' );
Code-Sprache: PHP (php)
Um mehrere unterschiedliche Inhaltstypen zu unterstützen, führe den Code in einer Schleife für jeden Inhaltstypen aus.