Wordpress - 使用Walker Class动态注入菜单项

时间:2013-01-04 12:40:43

标签: wordpress

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

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

所以我的菜单看起来像

  • 主页
  • 博客
  • 新闻
  • 功能
  • 比赛 -
    • Comp1
    • 器Comp2

从单独的站点上的DB中提取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,我可以看到我创建的'psuedo Post'的动态内容,它永远不会附加到菜单上。

是否有更简单的方法来注入菜单项?

更新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;
  }

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

3 个答案:

答案 0 :(得分:1)

您只需将竞赛菜单项的HTML附加到$output,例如,

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

这就是$ output通过引用('&amp;')传递给start_el()的原因。

这个例子可能很简单,因为你必须将它调整为WP生成的菜单项所遵循的原型,但它说明了原理。创建模拟WordPress项目并尝试欺骗WordPress为您完成工作,似乎不是正确的方法。

答案 1 :(得分: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中,然后替换您的菜单标题并与您的相关联。

答案 2 :(得分:0)

在回答问题和答案后,我添加了&#39; GOOGLE&#39; “竞赛”下的子菜单项目&#39;父菜单所以这里是编辑菜单栏的完整解决方案。

  • 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。

  

工作正常。