仅将第一个和最后一个类添加到顶层菜单

时间:2013-05-26 作者:AlecRust

我用的是WordPress Menu 要创建如下结构的导航,请执行以下操作:

主页关于联系人子页kuroi\'s response here 我可以添加first-menu-itemlast-menu-item 以上列表项的类别:

function add_first_and_last($output) {
    $output = preg_replace(\'/class="menu-item/\', \'class="first-menu-item menu-item\', $output, 1);
    $output = substr_replace($output, \'class="last-menu-item menu-item\', strripos($output, \'class="menu-item\'), strlen(\'class="menu-item\'));
    return $output;
}
add_filter(\'wp_nav_menu\', \'add_first_and_last\');
然而last-menu-item 类被添加到子页列表项(因为它是最后一个),而不是联系人列表项。

问题:如何使此功能仅适用于菜单的顶级项?

谢谢

5 个回复
最合适的回答,由SO网友:s_ha_dum 整理而成

为此,我非常倾向于使用定制的助行器,但我想我已经成功地使用了部分代码和我自己的一些代码。

function add_position_classes_wpse_100781($classes, $item, $args) {
  static $fl;
  if (0 == $item->menu_item_parent) {
    $fl = (empty($fl)) ? \'first\' : \'middle\';
    $classes[] = $fl.\'-menu-item\';
  } 
  return $classes;
}
add_filter(\'nav_menu_css_class\',\'add_position_classes_wpse_100781\',1,3);

function replace_class_on_last_occurance_wpse_100781($output) {
    $output = substr_replace(
      $output, 
      \'last-menu-item \', 
      strripos($output, \'middle-menu-item\'), 
      strlen(\'middle-menu-item\')
    );
    return $output;
}
add_filter(\'wp_nav_menu\', \'replace_class_on_last_occurance_wpse_100781\');
我所做的是添加first-menu-itemmiddle-menu-item 仅在打开第一个筛选器的情况下转到顶级项目nav_menu_css_class. 然后用第二个过滤器替换最后出现的middle-menu-item 具有last-menu-item.

它适用于我尝试的几个测试用例。

SO网友:Hitesh Siddhapura

我对Bainternet代码没有什么修改,因为如果最后一项有子项,则此代码不起作用

function wpb_first_and_last_menu_class($items) {
    $items[1]->classes[] = \'first-menu-item\'; // add first class

    $cnt = count($items);
    while($items[$cnt--]->post_parent != 0); // find last li item
    $items[$cnt+1]->classes[] = \'last-menu-item\'; // last item class
    return $items;
}
add_filter(\'wp_nav_menu_objects\', \'wpb_first_and_last_menu_class\'); //filter to iterate each menu

SO网友:Bainternet

类似这样:

function add_first_and_last_classes_wpa100781($items) {
    $items[1]->classes[] = \'first\';
    $items[count($items)]->classes[] = \'last\';
    return $items;
}

add_filter(\'wp_nav_menu_objects\', \'add_first_and_last_classes_wpa100781\');

SO网友:Floyd

我建议:

(1)skip adding the first menu item class. 这是您不需要的额外php。使用ul > li:first-child 将允许您以CSS中的第一个菜单项为目标,或者作为jQuery选择器。:first-child 具有强大的浏览器支持(超过:last child,因此我将为最后一个菜单项添加一个类)。

(2)Find the last top-level menu item and add a class to it. 将此代码放入主题的函数中。php文件,它将只在最后一个顶级导航项中添加一个类,而不是像这里其他答案中的许多代码片段一样,在最后一个导航项中添加一个类。

// Add a class to the last top-level menu item
function fancy_last_menu_item_class($items) {
    // Create an empty array to hold the array ID\'s of top level menu items
    $topLevelMenuItemIDs = array();

    // Loop through all of the menu $items
    for($i=0,$count=count($items);$i<$count;$i++){
        // Check if the \'menu_item_parent\' property is set to \'0\'
        if($items[$i]->menu_item_parent == 0){   
            // This item has no parent menu items, so it\'s top-level.
            // Add its array ID to the top level menu item IDs array.
            $topLevelMenuItemIDs[] = $i;
        }
    }

    // Count how many top level nav items were found, so you can target the last one
    $topLevelMenuItemCount = count($topLevelMenuItemIDs);

    // Add a class to the last top level navigation item.
    $lastMenuItemClass = \'last-menu-item\';
    $items[$topLevelMenuItemIDs[--$topLevelMenuItemCount]]->classes[] = $lastMenuItemClass;

    // Return the items with the altered last item
    return $items;
}
// Hook the last menu item class to the wp_nav_menu_objects filter
add_filter(\'wp_nav_menu_objects\', \'fancy_last_menu_item_class\');

SO网友:majick

参加派对很晚了,但我也在寻找一种可以处理子菜单和子菜单的方法,最后我想到了这个方法,把它写下来,并附上评论,以帮助我了解它。

基本上,它不会尝试向后循环,而是向前循环并检查下一个菜单项父项。

 add_filter(\'wp_nav_menu_objects\', \'first_last_nav_menu_item_classes\');

 function first_last_nav_menu_item_classes($items) {

    // --- loop items to add classes ---
    $itemcount = count($items);
    $lastmenuitems = $lastsubmenuitems = $lastsubsubmenuitems = array();
    foreach ($items as $i => $item) {

        // --- get menu item parent ---
        $itemparent = $item->menu_item_parent;

        // --- maybe get next item and parent ---
        if (isset($nextitem)) {unset($nextitem);}
        if (isset($items[($i+1)])) {
            $nextitem = $items[($i+1)];
            $nextparent = $nextitem->menu_item_parent;
        }

        if ($itemparent == 0) {

            // --- clear for top level menu item ---
            if (isset($parentmenu)) {unset($parentmenu);}
            $foundsubmenu = $foundsubsubmenu = false;

            // --- set first menu class and store current menu index ---
            if ($i == 1) {$items[$i]->classes[] = \'first-menu-item\';} else {$lastfoundmenu = $i;}

            // --- check if next item is a submenu of this menu ---
            if ( isset($nextitem) && ($nextparent == $item->ID) ) {$parentmenu = $item->ID;}

            // --- store last found submenu and subsubmenu items ---
            if (isset($lastfoundsubmenu)) {
                $lastsubmenuitems[] = $lastfoundsubmenu;
                unset($lastfoundsubmenu);
            }
            if (isset($lastfoundsubsubmenu)) {
                $lastsubsubmenuitems[] = $lastfoundsubsubmenu;
                unset($lastfoundsubsubmenu);
            }

        } elseif (isset($parentmenu)) {

            // --- subsubmenu items ---         
            if ( isset($parentsubmenu) && ($itemparent == $parentsubmenu) ) {

                // --- set first subsubmenu item class ---
                if (!$foundsubsubmenu) {
                    $items[$i]->classes[] = \'first-subsubmenu-item\';
                    $foundsubsubmenu = true;
                }

                // --- store last subsubmenu item ---
                if ( !isset($nextitem) || ( isset($nextitem) && ($nextparent != $parentsubmenu) ) ) {
                    $items[$i]->classes[] = \'last-subsubmenu-item\';
                }

            } elseif ($itemparent == $parentmenu) {

                // --- submenu items ---
                $foundsubsubmenu = false;

                // --- add class for first submenu item ---
                if (!$foundsubmenu) {
                    $items[$i]->classes[] = \'first-submenu-item\';
                    $foundsubmenu = true;
                }

                // --- store last submenu item ---
                if ( !isset($nextitem) || ( isset($nextitem) && ($nextparent != $parentmenu) ) ) {
                    $lastfoundsubmenu = $i;
                }

                // --- set parent submenu ---
                if ( isset($nextitem) && ($nextparent == $item->ID) ) {$parentsubmenu = $item->ID;}
            } 
        }
    }

    // --- if submenu or subsubmenu item is last item ---
    if (isset($lastfoundsubmenu)) {$lastsubmenuitems[] = $lastfoundsubmenu;}
    if (isset($lastfoundsubsubmenu)) {$lastsubsubmenuitems[] = $lastfoundsubsubmenu;}

    // --- add classes to last found menu items ---
    $items[$lastfoundmenu]->classes[] = \'last-menu-item\';
    if (count($lastsubmenuitems) > 0) {
        foreach ($lastsubmenuitems as $index) {
            $items[$index]->classes[] = \'last-submenu-item\';
        }
    }
    if (count($lastsubsubmenuitems) > 0) {
        foreach ($lastsubsubmenuitems as $index) {
            $items[$index]->classes[] = \'last-subsubmenu-item\';
        }
    }

    return $items;
 }
很好的包含我的主题,希望它能帮助别人看。

结束

相关推荐

Custom menus not showing

作为我上一次关于菜单的未解决查询的后续,这个问题已经进一步扩展。我的菜单没有打印代码中的任何地方。我正在注册菜单功能。php:add_action( \'after_setup_theme\', \'your_newtheme_setup\' ); if ( ! function_exists( \'your_newtheme_setup\' ) ) : function your_newtheme_setup() { if (