如何使用自定义Walker类将自定义分类术语动态添加为现有菜单项的子菜单

时间:2019-12-01 作者:Spcaeyob

我有一个自定义的帖子类型,属于它,一个自定义的分类法。我试图让我的子主题动态地将属于该分类法的术语作为子菜单添加到主题菜单中某个列表项下。分类法是分层的,我想添加所有深度为1的术语,即具有适当缩进和与当前菜单相同样式的第一级和第二级术语。

我的策略是,我首先想到了使用wp\\u nav\\u menu items过滤器,但由于可能有许多术语,而且它们是分层的,因此我认为最好使用自定义walker来扩展walker\\u nav\\u menu类。

我遇到的问题是,当我尝试在自定义walker中调用get\\u terms()函数时,它会返回“无效的分类法”。我知道分类法已经注册,数据库中也有术语。在walker类中调用get\\u terms()时,它似乎在init之前被调用。由于分类法在init上注册,所以当walker类调用get\\u terms()时,分类法无效;

我尝试了什么,所以我尝试从类中取出get\\u terms()函数,并执行以下操作:

function get_mytax_terms() {
  $myterms= get_terms( array(
    \'taxonomy\' => \'mytax\',
    \'hide_empty\' => true
  ) );
  return $myterms;
}
add_action( \'init\' , get_mytax_terms() , 10 );
我甚至尝试将该变量设为全局变量,但它不返回任何术语,并且由于分类法无效而引发错误。var\\u转储仍然会给我“无效的分类法”错误。我继续阅读,在codex(Walker\\u Nav\\u菜单类页面)的一条评论中看到,我需要使用静态函数,并在custom Walker类中这样做:

/**
   * Get all terms of tax mytax
   */
  public static function init() {
    add_action( \'init\', array( get_called_class(), \'get_mytax_terms\' ), 10 );
  }
  public static function get_mytax_terms() {
    $myterms = get_terms( array(
      \'taxonomy\' => \'mytax\',
      \'hide_empty\' => true
    ) );
    return $myterms ;
    var_dump($myterms );
  }
该var\\u转储运行,但仍返回“无效分类法”错误。

编辑我尝试将自定义分类法更改为内置分类法“category”,然后我的功能开始工作。使用“mytax”仍然会给我带来无效的分类法。

自定义分类已注册到

add_action( \'init\', \'custom_register_taxonomies\');
I am now fairly certain that this issue is due to the wp_nav_menu call coming earlier than the registration of my custom taxonomy.

问题是,在之前注册自定义分类法是否安全init?

如上所述,我在custom walker类中使用静态函数对吗?

推迟wp_nav_menu 调用,从“我的孩子”主题中的自定义位置调用。而不是让父主题调用它,并调整我的walker类和/或分类注册函数?

我是走对了还是错过了什么?

当前情况我在下面列出了我的定制助行器。任何提示都将不胜感激。

/* ---- Add mytax taxonomy terms to menu ---- */
class Walker_Add_Myterms extends Walker_Nav_Menu {
  // Insert a submenu
  function end_el( &$output, $item, $depth=1, $args=array() ) {
      // if the current menu item being output is parentmenuitem
      if( \'parentmenuitem\' == $item->title ){
          // get all terms
          $myterms = get_terms( array(
              \'taxonomy\' => \'mytax\',
              \'hide_empty\' => true,
          ) );
          if ( ! empty( $myterms ) && ! is_wp_error( $myterms ) ) {
              // start a new list
              $output .= \'<ul>\';
              // iterate over each type and add an li
              foreach( $myterms $myterm){
                  $term_url = get_term_link( $myterm->term_id , \'mytax\');
                  $name = $myterm->name;
                  $format = \'<li><a href="%s">%s</a></li>\';
                  $output .= sprintf( $format, $term_url, $name );
              }
              // close the list
              $output .= \'</ul>\';
          }
      }
      // close the parent li
      $output .= "</li>\\n";  
  }
}
wp_nav_menu( array(
    \'theme_location\'  => \'expanded\',
    \'container\'       => \'ul\',
    \'menu_class\'      => \'expanded-menu sub-menu active\',
    \'walker\'          => new Walker_Add_Myterms
) );

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

好吧,我知道了。它不是很平滑,但至少它能按我所希望的那样工作。必须进行一些重构。

问题是wp\\u nav\\u menu()在分类法注册之前被调用。我不小心把它放在了我的主题函数中。php并忘记了它,然后在我的标题中再次调用它。php。这就是为什么它似乎有效,但我仍然得到了无效的分类错误和损坏的菜单。

这是最后一节步行课:

class Walker_Add_Myterms extends Walker_Nav_Menu {
    public function end_el( &$output, $item, $depth=1, $args=array() ) {
    // if the current menu item being output has class "uthyrning"
    if( in_array( \'parentliitemclass\' , $item->classes ) ){
        // get all terms
        $myterms = get_terms( array(
            \'taxonomy\'      => \'mytax\',
            \'hide_empty\'    => true,
            \'parent\'        => 0,
            ) );
        if ( ! empty( $myterms ) && ! is_wp_error( $myterms ) ) {
            // Insert a submenu
            $output .= \'<ul class="sub-menu">\';
            // iterate over each type and add an li
            foreach( $myterms as $myterm){

                $term_url   = get_term_link( $myterm->term_id , \'mytax\' );
                $name       = $myterm->name;
                $li_id      = \'id="term-item-\' . $myterm->term_id . \'"\';
                $li_classes = \'menu-item menu-item-type-taxonomy menu-item-object-mytax term-item-\' . $myterm->term_id;
                $wrap_class = \'class="ancestor-wrapper"\';
                $format     = \'<li %s class="%s"><div %s><a href="%s">%s</a></div></li>\';

                // Get child terms ,and if they exist, create sub-menu with term children

                $children = get_term_children( $myterm->term_id, \'mytax\' );
                if( isset($children) && ! is_wp_error( $children ) && sizeof($children) > 0) {
                    $li_classes .= \' menu-item-has-children\';
                    $child_items = \'\';
                    foreach ( $children as $child ) {
                        $child_term = get_term( $child, \'mytax\' );
                        $child_item     =   \'<li id="term-item-\' . $child_term->term_id . \'" class="menu-item menu-item-type-taxonomy menu-item-object-mytax term-item-\' . $child_term->term_id . \'"><div class="ancestor-wrapper">\';
                        $child_item     .=  \'<a href="\' . get_term_link( $child_term, \'mytax\' ) . \'">\' . $child_term->name . \'</a>\';
                        $child_item     .=  \'</div></li>\';
                        $child_items    .=  $child_item;
                    }
                    $format         = \'<li %s class="%s"><div %s><a href="%s">%s</a>\';
                    $format         .= \'<button class="toggle sub-menu-toggle fill-children-current-color" data-toggle-target=".menu-modal .term-item-\' . $myterm->term_id . \' > .sub-menu" data-toggle-type="slidetoggle" data-toggle-duration="250" aria-expanded="false"><span class="screen-reader-text">Visa undermeny</span><svg class="svg-icon" aria-hidden="true" role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" width="20" height="12" viewBox="0 0 20 12"><polygon fill="" fill-rule="evenodd" points="1319.899 365.778 1327.678 358 1329.799 360.121 1319.899 370.021 1310 360.121 1312.121 358" transform="translate(-1310 -358)"></polygon></svg></button>\';
                    $format         .= \'</div><ul class="sub-menu">\';
                    $format         .= $child_items . \'</ul></li>\';
                }

                // END Child terms
                $output     .= sprintf( $format, $li_id, $li_classes, $wrap_class, $term_url, $name );
            }
            // close the list
            $output .= \'</ul>\';
        }
    }
    // close the parent li
    $output .= "</li>\\n";  
    }
}
最后,我还从父主题复制了调用wp\\u nav\\u menu()的模板部分,并用上面我自己的扩展类替换了默认的walker\\u nav\\u menu类。