1

我正在尝试引入一些动态(非 WP)内容来填充 Wordpress 中的菜单。为此,我扩展了 Walker 类,如下所示:

http://www.kriesi.at/archives/improve-your-wordpress-navigation-menu-output

所以我的菜单看起来像

  • 博客
  • 消息
  • 特征
  • 比赛——
    • 比较1
    • 比较2

Comp1 和 Comp2 是从单独站点上的数据库中提取的。它们只是指向外部站点的链接,因此唯一相关的值是“Comp Title”和“Comp URL”

我班的主要方法是:

 function start_el(&$output, $item, $depth, $args)
    {

        global $wp_query;
        $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

        $class_names = $value = '';

        $classes = empty( $item->classes ) ? array() : (array) $item->classes;

        $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
        $class_names = ' class="'. esc_attr( $class_names ) . '"';

        $output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $class_names .'>';

        $attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
        $attributes .= ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
        $attributes .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
        $attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'"' : '';

        $prepend = '<strong>';
        $append = '</strong>';
        $description  = ! empty( $item->description ) ? '<span>'.esc_attr( $item->description ).'</span>' : '';

        if($depth != 0)
        {
            $description = $append = $prepend = "";
        }

        if($item->title == 'Competitions')
        {
            $item_output = $args->before;
            $item_output .= '<a'. $attributes .'>';
            $item_output .= $args->link_before .$prepend.apply_filters(  'the_title', $item->title, $item->ID ).$append;
            $item_output .= $description.$args->link_after;
            $item_output .= '</a>';
            $item_output .= $args->after;

            $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );

            $this->loopComps($output , $args);

        }
        else
        {
            $item_output = $args->before;
            $item_output .= '<a'. $attributes .'>';
            $item_output .= $args->link_before .$prepend.apply_filters( 'the_title', $item->title, $item->ID ).$append;
            $item_output .= $description.$args->link_after;
            $item_output .= '</a>';
            $item_output .= $args->after;

            $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
        }
    }

然后loopComps方法是:(getGalleryComps()拉入动态内容)

 function loopComps($output , $args)
    {
        $openComps = $this->getGalleryComps();
        foreach($openComps as $comp)
        {
            $item =  new StdClass;
            $item->ID = 9999;
            $item->post_author = 5;
            $item->post_date = '2012-11-16 10:48:44';
            $item->post_date_gmt = '2012-11-16 10:48:44';
            $item->title = $comp['competition_name'];
            $item->post_type = 'nav_menu_item';
            $item->post_name = $comp['competition_name'];
            $item->post_title = $comp['competition_name'];
            $item->post_excerpt = $comp['competition_name'];
            $item->guid = $comp['competition_name'];
            $item->url = 'http://www.mycomps';
            $item->post_status = 'publish';
            $item->post_parent = 0;
            $item->filter = 'raw';
            $item->menu_item_parent = '6845';
            $item->object_id = '99999';
            $item->object = 'custom';
            $item->type = 'custom';
            $item->classes = array(null , 'menu-item' , 'menu-item-type-custom' , 'menu-item-object-custom');
            $item->menu_order = 6;


            return $this->start_el($output, $item, 1, $args);


        }

    }

这一切似乎都很好,希望 $item 永远不会附加到实际菜单上。如果我在导航菜单循环期间打印出 $items,我可以看到我创建的“伪帖子”的动态内容在那里,它永远不会附加到菜单上。

有没有更简单的注入菜单项的方法?

更新 1:

我已将 loopComps 方法调整为:

 function loopComps($output)
    {
        $openComps = $this->getGalleryComps();

        $output .= '<ul>';
        foreach( $openComps as $openComp )
        {
            $output .= '<li><a href='.$openComp->url.'>'.$openComp['competition_name]'].'</a></li>';
        }
        $output .= '</ul>';

        return $output;
  }

由于这确实更有意义,但不能解决问题,因此数据在那里,但从未显示在菜单中。

4

3 回答 3

1

您应该只需要将比赛菜单项的 HTML 附加到$output,例如,

$output .= '<ul>';
foreach( $comps as $comp ) {
    $output .= '<li><a href='.$comp->url.'>.$comp->title.'</a></li>';
}
$output .= '</ul>';

这就是为什么 $output 通过引用 ('&') 传递给start_el().

此示例可能过于简单,因为您必须将其调整为 WP 生成的菜单项遵循的任何原型,但它说明了原理。创建模拟 WordPress 项目并试图诱使 WordPress 为您完成工作,这似乎不是正确的方法。

于 2013-01-04T20:44:43.433 回答
1

我不确定我是否正确理解了您的问题,但是既然您问了,所以我认为您可以使用钩子Is there an easier way of injecting menu items?轻松添加额外的菜单项,例如wp_nav_menu_items

add_filter( 'wp_nav_menu_items', 'your_custom_menu_item', 10, 2 );
function your_custom_menu_item ( $items, $args ) {
    // First get the data from your database and replace menu titles and links
    // then loop the result and add items
    $myMenu='<li><a href="#">External Links</a><ul>'; // parent
    $myMenu.='<li><a target="_blank" href="http://facebook.com">Facebook</a></li>';
    $myMenu.='<li><a target="_blank" href="http://google.com">Google</a></li></ul></li>';
    $items .= $myMenu;
    return $items;
}

只需将代码粘贴到您的菜单中functions.php,然后将您的菜单标题和链接替换为您的。

于 2013-01-04T21:21:08.830 回答
0

在查看问题和答案后,我在“竞赛”父菜单下添加了“GOOGLE”子菜单项,因此这里是编辑菜单栏的完整解决方案。

  • 1

    首先将此代码放在主要调用菜单栏的位置,它应该在 header.php 中并更改我在评论中提到的自定义菜单

    class description_walker extends Walker_Nav_Menu
    {
      function start_el(&$output, $item, $depth, $args){
        global $wp_query;
        $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
        $class_names = $value = '';
        $classes = empty( $item->classes ) ? array() : (array) $item->classes;
        $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
        $class_names = ' class="'. esc_attr( $class_names ) . '"';
        $output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $class_names .'>';
        $attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
        $attributes .= ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
        $attributes .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
        $attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'"' : '';
        $prepend = '<strong>';
        $append = '</strong>';
        $description  = ! empty( $item->description ) ? '<span>'.esc_attr( $item->description ).'</span>' : '';
        if($depth != 0){
         $description = $append = $prepend = "";
        }
        if($item->title=='Competitions'){
          $item_output = $args->before;
          $item_output .= '<a'. $attributes .'>';
          $item_output .= $args->link_before .$prepend.apply_filters(  'the_title', $item->title, $item->ID ).$append;
          $item_output .= $description.$args->link_after;
          $item_output .= '</a>';
          $item_output .= $args->after;
          /* YOUR CUSTOM MENU OR SUBMENU -START- */
          $output .= '<ul class="sub-menu">';
          $output .= '<li><a href='.'http://www.google.com'.'>'.'GOOGLE'.'</a></li></ul>';
          /* YOUR CUSTOM MENU OR SUBMENU -END- */
          $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
        }else{
          $item_output = $args->before;
          $item_output .= '<a'. $attributes .'>';
          $item_output .= $args->link_before .$prepend.apply_filters( 'the_title', $item->title, $item->ID ).$append;
          $item_output .= $description.$args->link_after;
          $item_output .= '</a>';
          $item_output .= $args->after;
          $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
        }
      }
    }
    
    • 2 调用 wp_nav_menu 并传递我们刚刚创建的自定义 walker 对象。

    wp_nav_menu( array( 'container' =>false, 'menu_class' => 'menuPrincipal', 'echo' => true, 'before' => '', 'after' => '', 'link_before' => '', 'link_after' => '', 'depth' => 0, 'walker' => new description_walker()) );

它将在比赛菜单下添加 GOOGLE 子菜单

第一个答案是正确的,但类成员输出无法通过 loopComps 设置,而且我们不应该仅仅为了设置输出成员而返回输出,所以我们只需将直接子菜单设置为 walker。

它工作正常。

于 2015-07-11T07:32:47.987 回答