Wordpress - 确定菜单项是否包含子项

时间:2018-01-02 02:22:25

标签: php wordpress

我已经搜索了几个小时,无法想出我认为简单的事情。我正在本地构建我的第一个Wordpress站点。我正在为我的functions.php文件创建一个基于this howto的函数,但我需要它有子菜单。我在Wordpress中创建了一个自定义菜单,有2个级别。

如果项目是父项,我需要将HTML代码(不是CSS类)添加到项目中。

奖励积分如果您可以告诉我人们如何知道菜单项可用的属性/属性(例如标题和网址) - 我无法在任何地方找到对此的引用!

这是我当前的代码,目前将所有菜单项显示为顶级项目。

function clean_custom_main_menu() {
    $menu_name = 'main-menu'; // specify custom menu slug
    $menu_list = '<ul id="menu">' ."\n";

    if ($menu_items = wp_get_nav_menu_items($menu_name)) { 
        $count = 0;
        $submenu = false;

        foreach ((array) $menu_items as $key => $menu_item) {
            $title = $menu_item->title;
            $url = $menu_item->url;
            $classes = $menu_item->classes; // does not work
            $has_children = $menu_item->has_children;  //does not work
            $parent_id = 0;

            // check if this item is a parent item with children
            //if ( $menu_item->menu_item_parent && $menu_item->menu_item_parent > 0 ) {
            //if(in_array('menu-item-has-children', $classes)){
            if ($has_children) {
                $parent_id = $menu_item->ID;
            }
            // if this item has a parent ID, it's a second-level item
            if ($parent_id != 0 && $parent_id == $menu_item->menu_item_parent ) {
               $submenu = true;
            }

            if (!$has_children) {
               // if this item has no submenu, write top-level code
                $menu_list .= "\t". '<li><a href="'. $url .'">'. $title .'</a></li>' ."\n";
            }
            // the "else" is not currently being hit
            //else {
            //    $menu_list .= "\t" . '<li><a href="#">' . $title . '<span class="arrow-down"></span></a></li>' . "\n";
           //    $menu_list .= '<ul class="sub">';
            //    // foreach (child) do children
            //    $menu_list .= '</ul>';
            //    $menu_list .= '</li>';
            //}
        }
    } else {
         $menu_list .= '<!-- no list defined -->';
    }
    $menu_list .= "\t". '</ul>' ."\n";
    echo $menu_list;
}

期望的输出:

 <ul id="menu">
  <li><a href="#">Home</a></li>
  <li>
    <a href="#">About <span class="arrow-down"></span></a>
    <ul class="sub">
        <li><a href="/about/services.html">Our Services</a></li>
        <li><a href="/about/what-we-do.html">What We Do</a></li>
    </ul>
 </li>
 <li>
    <a href="/top-level-item/">Top-Level Item</a>
 </li>
 <li><a href="#">Top-Level Item with Children <span class="arrow-down"></span></a>
    <ul class="sub">
        <li><a href="/top-level-item2/item1">Sub Item 1</a></li>
        <li><a href="/top-level-item2/item2">Sub Item 2</a></li>
        <li><a href="/top-level-item2/item3">Sub Item 3</a></li>
        <li><a href="/top-level-item2/item4">Sub Item 4</a></li>
    </ul>
 </li>
 <li><a href="/contact/">Contact</a></li>
</ul>

请注意:我不想使用步行者。我确信它可以以某种方式完成,因为我有一点工作,但是当Wordpress决定更新我制作的主题时,丢失了一切 - 与web-land完全不同,删除了我的所有文件。 D'哦!

2 个答案:

答案 0 :(得分:0)

<强> API

尝试执行var_dump($ menu_items),你会看到菜单项是post_type“nav_menu_item”的帖子,所以它们与post有相同的api。

数孩子

https://wordpress.stackexchange.com/questions/9374/get-the-post-children-count-of-a-post显示了使用$ wpdb访问子帖子计数的方法。您可以通过将parent_id设置为父项并将post_type设置为nav_menu_item然后对结果进行计数来使用get_posts执行此操作。

<强>类

post对象有一个classes数组。由于这不适合你,我会仔细检查你是如何尝试访问/使用该数组的,如果这没有帮助,请尝试调查walker函数以获得有关自定义实现的帮助。

答案 1 :(得分:0)

事实证明,人们已经在Wordpress文档中为我正在使用的函数wp_get_nav_menu_items()贡献了如何使用子菜单构建项目。这些让我开始,但他们并不完全正确,因为我有额外的跨度标签,并希望在不同的地方关闭我的A标签,但我能够最终使事情工作。以下是基于这些评论的最终代码:

function clean_custom_main_menu() {
    $menu_name = 'main-menu'; // specify custom menu slug
    $menu_list = '<ul id="menu">' ."\n";

    if ($menu_items = wp_get_nav_menu_items($menu_name)) { 
        $count = 0;
        $submenu = false;
        $parent_id = 0;
        $previous_item_has_submenu = false;

        foreach ((array) $menu_items as $key => $menu_item) {
            $title = $menu_item->title;
            $url = $menu_item->url;

            // check if it's a top-level item
            if ($menu_item->menu_item_parent == 0) {
                $parent_id = $menu_item->ID;
               // write the item but DON'T close the A or LI until we know if it has children!
                $menu_list .= "\t". '<li><a href="'. $url .'">'. $title;
            }

            // if this item has a (nonzero) parent ID, it's a second-level (child) item
            else {
                if ( !$submenu ) { // first item
                    // add the dropdown arrow to the parent
                    $menu_list .= '<span class="arrow-down"></span></a>' . "\n";
                    // start the child list
                    $submenu = true;
                    $previous_item_has_submenu = true;
                    $menu_list .= "\t\t" . '<ul class="sub">' ."\n";
               }

                $menu_list .= "\t\t\t" . '<li>';
                $menu_list .= '<a href="'.$url.'" class="title">'.$title.'</a>';
                $menu_list .= '</li>' ."\n";

                // if it's the last child, close the submenu code
                if ( $menu_items[ $count + 1 ]->menu_item_parent != $parent_id && $submenu ){
                    $menu_list .= "\t\t" . '</ul></li>' ."\n";
                    $submenu = false;
                }
            }

            // close the parent (top-level) item
            if (empty($menu_items[$count + 1]) || $menu_items[ $count + 1 ]->menu_item_parent != $parent_id )
            {
               if ($previous_item_has_submenu)
                {
                    // the a link and list item were already closed
                    $previous_item_has_submenu = false; //reset
                }
                else {
                    // close a link and list item
                    $menu_list .= "\t" . '</a></li>' . "\n";
                }
            }

            $count++;
        }
    } else {
         $menu_list .= '<!-- no list defined -->';
    }
    $menu_list .= "\t". '</ul>' ."\n";
    echo $menu_list;
}