显示当前父菜单和其子菜单-WordPress

5

我有一个主导航,所有的父级菜单都有子菜单。

例如:
Page A: About Us
child1
child2

Page B : Our services
Child 3
Child 4

我需要在页面上包含一个水平子菜单。但我的问题是,如果当前我们在A页面,那么A页面的所有子项只能在A页面上显示。 如果我们在B页面,则应该只显示B页面的子项。

A页面
子项1
子项2

就像这样,当我们转到B页面时,只会显示B页面的子项。

      <?php 
  $args = array(
   'theme_location'  => '',
   'menu'            => '13',  //nav menu id, which has about-us as a menu.
   'container'       => 'div',
   'container_class' => '',
   'container_id'    => '',
   'menu_class'      => 'menu',
   'menu_id'         => '',
   'echo'            => true,
   'fallback_cb'     => 'wp_page_menu',
   'before'          => '',
   'after'           => '',
   'link_before'     => '',
   'link_after'      => '',
   'items_wrap'      => '<ul id="%1$s" class="%2$s">%3$s</ul>',
   'depth'           => 0,
   'walker'          => ''
);
  $menu_items = wp_nav_menu($args);//wp_get_nav_menu_items(13);

我试着写了上面的代码,结果得到了所有父级项目及其子级。
有人能帮我吗?
简而言之,我想获取“关于我们”菜单条目的所有子级(即,我想将子项1和子项2作为一个带有标签的列表)。

如果您能展示一些您尝试过的代码,我们很乐意提供帮助。 - M Khalid Junaid
7个回答

5
请在主题的functions.php中编写此代码。
<?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;
}
}

然后,您可以使用wp_nav_menu(就像通常一样)在您的主题中显示它,但同时传递一个sub_menu标志以激活自定义子菜单函数:

<?php
wp_nav_menu( array(
  'theme_location' => 'primary',
  'sub_menu' => true
) );
?>

我稍微缩进了你的代码以提高可读性。如果您能解释一下当 sub_menu 标志传递给 wp_nav_menu 时的(新?)返回值,那就太好了。 - Felix
1
请不要未经参考原作者的情况下盗用代码。https://christianvarga.com/how-to-get-submenu-items-from-a-wordpress-menu-based-on-parent-or-sibling/ - BugHunterUK

3

在页面上,您首先获取所有页面,然后可以获取当前页面的ID,将其子页面存储为一个数组,并通过以下方式循环遍历该数组:

<?php
    // First get all the pages in your site
    $wp_query = new WP_Query();
    $all_pages = $wp_query->query(array('post_type' => 'page'));

    // Then get your current page ID and children (out of all the pages)
    $current_page_id = get_the_id();
    $current_page_children = get_page_children($current_page_id, $all_pages);

    // Loop through the array of children pages
    foreach ($current_page_children as $child_page) {
        // Echo whatever you want from the pages
    }
?>

编辑:这与您在后端创建的结构化菜单无关,它与直接在页面编辑部分中将页面作为另一个页面的子页面有关。


1
这是一个全能的操作。
<?php
global $wp_query;
if( empty($wp_query->post->post_parent) ) {
$parent = $wp_query->post->ID;
} else {
$parent = $wp_query->post->post_parent;
} ?>
<?php if(wp_list_pages("title_li=&child_of=$parent&echo=0" )): ?>
<div>
<ul>
<?php wp_list_pages("title_li=&child_of=$parent" ); ?>
</ul>
</div>
<?php endif; ?>

感谢所有的解决方案!

1

我写了一个函数来帮助解决这个问题,因为我找到的大多数示例都包括页面的子级,但不包括页面本身。只需将此函数添加到您的 functions.php 文件中:

<?php

// Display sub menu
function the_sub_menu()
{
    global $post;

    // Open list
    echo '<ul class="sub_menu">';

    // Sub page
    if($post->post_parent) {

        // Load parent
        $parent = get_post($post->post_parent);

        // Add parent to list
        echo '<li><a href="' . get_permalink($parent->ID) . '">' . $parent->post_title . '</a></li>';

        // Add children to list
        wp_list_pages('title_li=&child_of=' . $post->post_parent);

    // Parent page
    } else {

        // Add parent to list
        echo '<li class="current_page_item"><a href="' . get_permalink($post->ID) . '">' . $post->post_title . '</a></li>';

        // Add children to list
        wp_list_pages('title_li=&child_of=' . $post->ID);
    }

    // Close list
    echo '</ul>';
}

然后,要在页面中使用它,只需像这样调用它:
<?php get_header() ?>

    <?php while (have_posts()): the_post() ?>

        <!-- Include the sub menu! -->
        <?php the_sub_menu() ?>

        <article>
            <?php the_content() ?>
        </article>

    <?php endwhile ?>

<?php get_footer() ?>

2
据我所知,这不会按照菜单中定义的项目进行遍历,而是使用页面层次结构。 - Felix

0

首先,你需要将“child1”和“child2”页面设置为“关于我们”页面的子页面。

点击此处了解创建子页面的更多信息

一旦页面结构设置好了,你就可以使用这个函数(文档链接

<?php wp_list_pages( $args );  

 $args = array(
    'depth'        => 0,
    'show_date'    => '',
    'date_format'  => get_option('date_format'),
    'child_of'     => N,   //N here should be replaced by your About-us page ID. 
    'exclude'      => '',
    'include'      => '',
    'title_li'     => __('About Us'),   //here you can mention any title you like for the list that's echoed by this function
    'echo'         => 1,
    'authors'      => '',
    'sort_column'  => 'menu_order, post_title',
    'link_before'  => '',
    'link_after'   => '',
    'walker'       => '',
    'post_type'    => 'page',
    'post_status'  => 'publish' 
); ?>

同样适用于您的“我们的服务”页面,希望这可以解决您的问题。如果您遇到任何问题,请告诉我们,欢迎来到stackoverflow!

默认情况下,wp_list_pages会显示所有页面和子页面。但我只需要子页面。因此,title_li应该包含其父级的子代标题。所以我需要先检索当前父ID。添加了一些代码来完成所有这些操作。问题现在已经解决。感谢您的帮助和热烈欢迎。 - varun

0
一个快速而“肮脏”的解决方案。
我创建了以下文件.../wp-content/plugins/gabriel-submenu.php 其内容如下:
<?php
/**
 * @package Gabriel_SubMenu
 * @version 0.1
 */
/*
Plugin Name: Gabriel SubMenu
Plugin URI: http://www.nuage.ch
Description: My plugin to display a submenu
Author: Gabriel Klein
Version: 0.1
Author URI: http://www.nuage.ch
*/

function gab_submenu_content($a) {

        $d = array(
                'theme_location' => 'main_menu',
                'child_of'       => $a['id'],
                'echo'           => false,
                'sort_column'    => 'menu_order'
        );

        return wp_nav_menu( $d );

}

add_shortcode('gabsubmenu','gab_submenu_content' );


?>

然后在我的文章中,我有:

[gabsubmenu id=93]

其中id是父页面的ID。


-2

自定义菜单及其子菜单

function thewebpixel_header_menu(){ ?>
<a href="#" id="mobile-menu-trigger"> <i class="fa fa-bars"></i> </a>
<ul class="sf-menu fixed" id="menu">
    <?php
        $args = array(
        'order'                  => 'ASC',
        'orderby'                => 'menu_order',
        'post_type'              => 'nav_menu_item',
        'post_status'            => 'publish',
        'output'                 => ARRAY_A,
        'output_key'             => 'menu_order',
        'nopaging'               => true,
        'update_post_term_cache' => false );

        $items = wp_get_nav_menu_items( 'main', $args );
        $parents = array();
        foreach($items as $item )
          $parents[] = $item->menu_item_parent;

        function check_has_child($parents, $menu_id){

            if(in_array($menu_id, $parents))                     
              return "YES";
        else
          return "NO";  
         }       

        $flag = 0;
        $count = 0;
        foreach($items as $item ) { ?>
    <?php if( !$item->menu_item_parent ){ 
        if($count != 0 && $count != 5 && $flag == 2){ 
              echo '</ul></div></div></li>';
              $count=0; 
              $flag=0;
              }  

          if(check_has_child($parents, $item->ID ) == "YES")
          {
            $liclass = '';
            $aclass = 'class="sf-with-ul"';                 
          }else{

            $liclass = 'dropdown';
            $aclass = '';            
            }          
          ?> 
    <li class="<?php echo $liclass; ?>"><a <?php echo $aclass; ?> href="<?php echo $item->url;?>"><span><?php echo
        $item->title;?></span></a>
        <?php } ?>   
        <?php  if( $item->menu_item_parent){ if($flag != 2)$flag = 1;  ?>
        <?php if($flag == 1) {                                 
            $flag = 2;
            echo '<div class="sf-mega">';
             } 

            if($count == 0 ){
            echo '<div class="sf-mega-section"><ul>';
            }
            $count++;
            ?>                                                
    <li><a href="<?php echo $item->url; ?>">
        <i class="fa fa-angle-right"></i>
        <?php echo $item->title; ?>
        </a>
    </li>
    <?php
        if($count == 5){
          echo '</ul></div>';
          $count=0;
        }

        } ?>    
    <?php if( !$item->menu_item_parent && check_has_child($parents, $item->ID ) == "NO" ){ ?></li> <?php } ?>
    <?php }  ?>
</ul>
<?php } ?>

https://developer.wordpress.org/reference/functions/wp_get_nav_menu_items/上查找更多信息和示例。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接