Ich hatte noch etwas Zeit, mich selbst damit zu befassen (sorry, wenn ich jemandes Zeit verschwendet hätte), und ich dachte mir, dass der beste Weg, um das Hervorhebungsproblem zu lösen, darin besteht, etwas zu wiederholen _wp_menu_item_classes_by_context()
, darin besteht, das, tue, ein , das ist über alles hinweg Eltern und Vorfahren des Menüelements, das als Eltern meines benutzerdefinierten Beitragstyps fungiert, und fügen Klassen entsprechend hinzu.
Da ich auch wollte, dass die übergeordnete Seite für meinen benutzerdefinierten Beitragstyp repariert und einfach geändert werden kann, ohne dass alle Beiträge aktualisiert werden müssen, sobald sich der übergeordnete ändert, habe ich beschlossen, eine Option zu verwenden, anstatt die zu füllen post_parent
Feld meiner benutzerdefinierten Beiträge auszufüllen. Ich habe ACF dafür verwendet, da ich es sowieso in meinem Theme verwende, aber die standardmäßige Funktionalität der WordPress-Option würde es natürlich auch tun.
Für meine Bedürfnisse konnte ich den wp_nav_menu_objects
Filter nutzen. Außerdem musste ich die page_for_posts
Option so filtern , dass sie einen falschen / leeren Wert zurückgibt. Dadurch wird vermieden, dass die Seite mit den Standardbeiträgen ebenfalls hervorgehoben wird.
Beachten Sie, dass ich nicht den ganzen Weg gegangen bin, der Filter fügt nur die Klassen current-menu-ancestor
und hinzu current-menu-parent
, da dies für meine Bedürfnisse ausreichte!
/**
* Filters the `page_for_posts` option on specific custom post types in
* order to avoid the wrong menu item being marked as
* `current-page-parent`.
*
* @see _wp_menu_item_classes_by_context()
*/
function wpse13308_pre_option_page_for_posts_filter()
{
$types = array
(
'my_custom_post_type_x',
'my_custom_post_type_y',
'my_custom_post_type_z'
);
if(in_array(get_post_type(), $types))
{
return 0;
}
return false;
}
add_filter('pre_option_page_for_posts', 'wpse13308_pre_option_page_for_posts_filter');
/**
* Returns the current posts parent page ID
*
* @return int
*/
function wpse13308_get_parent_page_id()
{
$postType = get_post_type();
$parentPageId = null;
switch($postType)
{
case 'my_custom_post_type_x':
case 'my_custom_post_type_y':
case 'my_custom_post_type_z':
$parentPageId = (int)get_field('page_for_' . $postType, 'options')->ID;
break;
case 'post':
$parentPageId = (int)get_option('page_for_posts');
break;
}
return $parentPageId;
}
/**
* Adds proper context based classes so that the parent menu items are
* being highlighted properly for custom post types and regular posts.
*
* @param array $menuItems
* @return array
*
* @see _wp_menu_item_classes_by_context()
*/
function wpse13308_wp_nav_menu_objects_filter(array $menuItems)
{
$parentPageId = wpse13308_get_parent_page_id();
if($parentPageId !== null)
{
$activeAncestorItemIds = array();
$activeParentItemIds = array();
foreach($menuItems as $menuItem)
{
if((int)$parentPageId === (int)$menuItem->object_id)
{
$ancestorId = (int)$menuItem->db_id;
while
(
($ancestorId = (int)get_post_meta($ancestorId, '_menu_item_menu_item_parent', true)) &&
!in_array($ancestorId, $activeAncestorItemIds)
)
{
$activeAncestorItemIds[] = $ancestorId;
}
$activeParentItemIds[] = (int)$menuItem->db_id;
}
}
$activeAncestorItemIds = array_filter(array_unique($activeAncestorItemIds));
$activeParentItemIds = array_filter(array_unique($activeParentItemIds));
foreach($menuItems as $key => $menuItem)
{
$classes = $menuItems[$key]->classes;
if(in_array(intval($menuItem->db_id), $activeAncestorItemIds))
{
$classes[] = 'current-menu-ancestor';
$menuItems[$key]->current_item_ancestor = true;
}
if(in_array($menuItem->db_id, $activeParentItemIds))
{
$classes[] = 'current-menu-parent';
$menuItems[$key]->current_item_parent = true;
}
$menuItems[$key]->classes = array_unique($classes);
}
}
return $menuItems;
}
add_filter('wp_nav_menu_objects', 'wpse13308_wp_nav_menu_objects_filter');
Der Vollständigkeit halber könnte das Abrufen der übergeordneten ID beim Auffüllenpost_parent
(siehe @ Bainternets Antwort ) anstelle der Verwendung von Optionen ungefähr so aussehen:
/**
* Returns the current posts parent page ID
*
* @return int
*/
function wpse13308_get_parent_page_id()
{
$parentPageId = null;
$post = get_post();
switch($post->post_type)
{
case 'my_custom_post_type_x':
case 'my_custom_post_type_y':
case 'my_custom_post_type_z':
$parentPageId = (int)$post->post_parent;
break;
case 'post':
$parentPageId = (int)get_option('page_for_posts');
break;
}
return $parentPageId;
}