如何获得单独的儿童菜单?

时间:2017-03-07 作者:Peter Westerlund

没想到我会问这个问题。但是是的,这是真的。Wordpress中似乎没有单独的子菜单?

我绝对不是Wordpress的初学者。多年来一直在it领域工作和发展。

但是,可能需要进行一次大的演练,以获得单独的子菜单/子菜单。但我想在这里得到的答案更像是;

Is it really true there\'s no simple built-in solution?

我真的在这个网站和其他网站上搜索过答案,但很难找到答案。这似乎都是关于下拉列表。我现在太累了!

可以说我也在经营Woocommerce。但没有,他们的文档中也没有答案。关于“二级菜单”的内容很多。但这不一样。我需要亲子关系。

编辑:

Following code example and output example has been added/changed to work as an example of a case scenario:

这是我的代码:

    <nav class="parent">
        <?php
        wp_nav_menu(
            array(
                \'theme_location\'  => \'primary\',
                \'container_class\' => \'primary-navigation\',
                )
        );
        ?>
    </nav><!-- #parent -->

    // Following menu should only be shown if the selected menu item from the above menu has child items. Show them here below. How do I make these two menus to have a connection to each other?
    <nav class="child">
        <?php
        wp_nav_menu(
            array(
                \'theme_location\'  => \'primary\',
                \'container_class\' => \'primary-child-navigation\',
                )
        );
        ?>
    </nav><!-- #child -->


The output 结果如下:

主页|Bags | 鞋帽

背包|Weekend Bags | 旅行箱|手持式,现在我们进入周末包页面 就这么简单

编辑2:第一个问题是depth 属性似乎不适用于wp_nav_menu(). 不能只有顶级吗?

4 个回复
最合适的回答,由SO网友:Peter Westerlund 整理而成

建立the solution. 把这个放进你的function.php 文件:

// add hook
add_filter( \'wp_nav_menu_objects\', \'my_wp_nav_menu_objects_sub_menu\', 10, 2 );
// filter_hook function to react on sub_menu flag
function my_wp_nav_menu_objects_sub_menu( $sorted_menu_items, $args ) {
  if ( isset( $args->sub_menu ) ) {
    $root_id = 0;

    // find the current menu item
    foreach ( $sorted_menu_items as $menu_item ) {
      if ( $menu_item->current ) {
        // set the root id based on whether the current menu item has a parent or not
        $root_id = ( $menu_item->menu_item_parent ) ? $menu_item->menu_item_parent : $menu_item->ID;
        break;
      }
    }

    // find the top level parent
    if ( ! isset( $args->direct_parent ) ) {
      $prev_root_id = $root_id;
      while ( $prev_root_id != 0 ) {
        foreach ( $sorted_menu_items as $menu_item ) {
          if ( $menu_item->ID == $prev_root_id ) {
            $prev_root_id = $menu_item->menu_item_parent;
            // don\'t set the root_id to 0 if we\'ve reached the top of the menu
            if ( $prev_root_id != 0 ) $root_id = $menu_item->menu_item_parent;
            break;
          } 
        }
      }
    }
    $menu_item_parents = array();
    foreach ( $sorted_menu_items as $key => $item ) {
      // init menu_item_parents
      if ( $item->ID == $root_id ) $menu_item_parents[] = $item->ID;
      if ( in_array( $item->menu_item_parent, $menu_item_parents ) ) {
        // part of sub-tree: keep!
        $menu_item_parents[] = $item->ID;
      } else if ( ! ( isset( $args->show_parent ) && in_array( $item->ID, $menu_item_parents ) ) ) {
        // not part of sub-tree: away with it!
        unset( $sorted_menu_items[$key] );
      }
    }

    return $sorted_menu_items;
  } else {
    return $sorted_menu_items;
  }
}
然后这样使用:

<?php
wp_nav_menu(
    array(
        \'theme_location\'    => \'primary\',
        \'container_class\'   => \'primary-navigation\',
        \'depth\' => 1

        )
);
wp_nav_menu(
    array(
        \'theme_location\'    => \'primary\',
        \'container_class\'   => \'primary-child-navigation\',
        \'sub_menu\'       => true

        )
);
?>

SO网友:Otkelbay Akberdi

您好,我为您提供了两个功能:

1) 使用此功能,您可以通过post id获取导航菜单子项:

function get_the_nav_menu_children_by_post_id($post_id)
{
    global $wpdb;
    $results = $wpdb->get_results("SELECT post_id FROM `wp_posts` p join wp_postmeta m ON p.ID = m.post_id WHERE post_type = \'nav_menu_item\' and meta_key = \'_menu_item_object_id\' and meta_value = $post_id");

    if (count($results)) {
        $result = $results[0];
        if($result->post_id){
            $menu_id = $result->post_id;
            $items = $wpdb->get_results("select * from wp_posts where ID in (SELECT meta_value FROM `wp_posts` p join wp_postmeta m on p.ID = m.post_id  WHERE p.ID in (SELECT post_id from wp_postmeta where meta_key = \'_menu_item_menu_item_parent\' and meta_value = $menu_id) and meta_key = \'_menu_item_object_id\')");
            return $items;
        }
    }
    return false;
}
2)或通过导航中项目的menu\\u id:

function get_the_nav_children($menu_id){
    global $wpdb;
    $items = $wpdb->get_results("select * from wp_posts where ID in (SELECT meta_value FROM `wp_posts` p join wp_postmeta m on p.ID = m.post_id  WHERE p.ID in (SELECT post_id from wp_postmeta where meta_key = \'_menu_item_menu_item_parent\' and meta_value = $menu_id) and meta_key = \'_menu_item_object_id\')");
    return $items;
}

SO网友:Svartbaard

你所说的独立子菜单到底是什么意思?你能提供一个用例吗?

我对您的问题的理解是,您希望在主菜单中插入一个单独的菜单,而不需要在后端将这些项作为子项添加。

如果我正确理解了你的问题,几年前我也做过类似的事情,所以很可能是这样。有一种方法可以将菜单与主菜单结合使用,但您需要重新构建菜单。

请参见以下内容:

https://codex.wordpress.org/Class_Reference/Walker

SO网友:Freize

我也遇到了类似的问题,同样感到惊讶的是,WP并没有让这件事变得容易。我尝试了各种“函数脚本”,但都有问题。彼得-我以为你的剧本here 这是我所需要的,但它似乎忽略了WP为每个页面提供的“订单”选项。

我用CSS完成了大部分工作,页面中只有一小块PHP。php

<?php if(!$post->post_parent){
$children = wp_list_pages("title_li=&child_of=".$post->ID."&echo=0");
}else{
if($post->ancestors)
{
$ancestors = end($post->ancestors);
$children = wp_list_pages("title_li=&child_of=".$ancestors."&echo=0");
}
}
if ($children) {
?>
<ul> <?php echo $children; ?></ul>
<?php } ?>
这是基于Mike Lee . 非常简单,非常适合我。