按照我们的习惯(或者只是我个人的习惯),习惯了在网页的上方显示导航菜单。Wordpress默认的模板并没有导航菜单,而有些喜欢的模板导航菜单中只有首页和页面,有些带有分类的导航主题自己却不喜欢。今天就教大家来解决这个矛盾。当然,如果你是自制主题的话,熟练的掌握wp_list_categories和wp_list_pages这两个函数,也可以让你随心所欲的定义导航内容。

wp_page_menu

wordpress 2.7 之后增加了一个wp_page_menu函数,用来显示导航菜单。用法如下:

<div id="navbar">
         <?php wp_page_menu('show_home=1'); ?>
</div>

这样就能显示包含“首页”的导航(如:首页 关于)。或者可以这样调用,以下代码等效于上面的代码:

<?php wp_page_menu('show_home=1&menu_class=navbar'); ?>

这样的好处是少了一个div嵌套。

多方便的一个函数,但可惜的是只能显示首页和页面,并不能显示分类。不过作为开源的wordpress,有什么是不能实现的呢?wp_page_menu定义在/wp-includes/post-template.php文件中,通过对源代码的分析我们可以知道,其实wp_page_menu()调用了wp_list_pages(),而wp_list_pages()的功能是显示页面列表。源代码中是这样定义的

$menu .= str_replace( array( "\r", "\n", "\t" ), '', wp_list_pages($list_args) );

那么,如果我们想在导航中显示分类,只需要把wp_list_categories加入到$menu即可

$menu .= str_replace( array( "\r", "\n", "\t" ), '', wp_list_categories('echo=0&title_li=').wp_list_pages($list_args) );

这样就达到了显示分类列表的目的,此时分类列表显示在首页和自定义的页面之间,如果想让分类列表显示在页面列表之后,可以把这一行代码修改为

$menu .= str_replace( array( "\r", "\n", "\t" ), '', wp_list_pages($list_args). wp_list_categories('echo=0&title_li='));

这样修改以后,当我们调用wp_page_menu的时候,导航菜单里就包含了分类。

具体做法

以上分析是可行的,但是需要修改源文件,这样一来就对以后升级wordpress带来了麻烦。那应该怎么做呢?方法很多,实质上就是灵活应用wp_list_pages和wp_list_categories的问题。

方法一:

直接调用以下代码

<ul id="navbar">
         <li><a href="<?php bloginfo('home'); ?>">首页</a></li>
         <?php wp_list_categories('title_li='); wp_list_pages('title_li='); ?>
</ul>

方法二:

首先把以下代码复制到主题下的functions.php文件中

function dm_page_menu( $args = array() ) {
 $defaults = array('sort_column' => 'menu_order, post_title', 'menu_class' => 'menu', 'echo' => true, 'link_before' => '', 'link_after' => '');
 $args = wp_parse_args( $args, $defaults );
 $args = apply_filters( 'wp_page_menu_args', $args );

 $menu = '';

 $list_args = $args;

 // Show Home in the menu
 if ( isset($args['show_home']) && ! empty($args['show_home']) ) {
  if ( true === $args['show_home'] || '1' === $args['show_home'] || 1 === $args['show_home'] )
   $text = __('Home');
  else
   $text = $args['show_home'];
  $class = '';
  if ( is_front_page() && !is_paged() )
   $class = 'class="current_page_item"';
  $menu .= '<li ' . $class . '><a href="' . get_option('home') . '">' . $args['link_before'] . $text . $args['link_after'] . '</a></li>';
  // If the front page is a page, add it to the exclude list
  if (get_option('show_on_front') == 'page') {
   if ( !empty( $list_args['exclude'] ) ) {
    $list_args['exclude'] .= ',';
   } else {
    $list_args['exclude'] = '';
   }
   $list_args['exclude'] .= get_option('page_on_front');
  }
 }

 $list_args['echo'] = false;
 $list_args['title_li'] = '';
 $menu .= str_replace( array( "\r", "\n", "\t" ), '', wp_list_categories('echo=0&title_li=').wp_list_pages($list_args) );

 if ( $menu )
  $menu = '<ul id="' . $args['menu_class'] . '">' . $menu . '</ul>';

 $menu = apply_filters( 'wp_page_menu', $menu, $args );
 if ( $args['echo'] )
  echo $menu;
 else
  return $menu;
}

然后直接调用dm_page_menu即可

<?php dm_page_menu('show_home=1&menu_class=navbar'); ?>

这两种方法各有优缺点,方法一简洁,但不支持filters,如果有插件使用wp_page_menu或wp_page_menu_args的filter就会无效。方法二稍微麻烦了一点,但是继承了原生wp_page_menu的所有特性,兼容性好些。

当然还有其它方法,比如使用get_categories和get_pages,这又是更底层的调用,有兴趣的可以研究一下。

掌握了这些函数和方法,你就可以按照自己的需求自定义你的导航菜单,比如除了显示分类和页面之外,你还可以增加一些其它的链接,比如增加一个“论坛”的菜单。这里就不放出具体的代码了,留给大家思考吧,我想只要你有一点的html基础就应该怎么添加。

什么?你还是不会?那就留言吧,把你的疑问提出来,大家一起讨论。

添加评论

17 条评论

  1. 1 F

    万戈

    2009-12-18 星期五 12:06

    原来还有wp_page_menu这么个函数,新鲜事

    回复
    • DDBug

      2009-12-18 星期五 14:31

      2.7后就有了,可能是你没注意吧

      回复
  2. 2 F

    SErHo

    2009-12-20 星期天 17:08

    我那个主题不适合那样做,我的分类太多了,呵呵

    回复
  3. 3 F

    卢松松

    2009-12-20 星期天 19:29

    相当于自己设计来的快些呢!

    回复
  4. 4 F

    vela

    2009-12-27 星期天 03:01

    使用了方法2,但是在这个地方
    $menu .= str_replace( array( “\r”, “\n”, “\t” ), ”, wp_list_categories(‘echo=0&title_li=’).wp_list_pages($list_args) );

    提示缺少一个右边括号,不知道在哪里添加

    Parse error: syntax error, unexpected T_STRING, expecting ‘)’

    回复
    • DDBug

      2009-12-27 星期天 12:55

      不会吧?我现在用的就是这个,没有问题,你把你的functions.php的代码发到我邮箱里,我帮你看一下

      回复
      • vela

        2009-12-28 星期一 22:15

        好的,我发过去了,你帮我看看

        回复
  5. 5 F

    starer

    2010-03-20 星期六 16:04

    你好!!
    第二种怎么用呀??怎么调用函数?下边的代码

    放哪呀???还有那些很多的代码是覆盖还是放哪呀??
    我用了一下怎么都进不去了???

    回复
  6. 6 F

    深圳SEO

    2010-10-15 星期五 11:59

    你好,就不懂代码,我做了个博客,就是解决不了这个导航的问题,一直很郁闷,看了你的文章我还是看不懂,希望你有空到我的博客看看,帮我解决下这个问题,谢谢!http://www.fcseo.net/

    回复
  7. 7 F

    Wener

    2010-12-07 星期二 01:59

    我试了下你的方法,我觉得就wp_page_menu就可以,把分类加到导航栏后感觉有点不伦不类的,毕竟一个页面和一个分类是不同的,有了云标签后就可以了吧。

    回复
  8. 8 F

    Wener

    2010-12-07 星期二 02:00

    除非把特定的分类加入到特定的导航栏位置。

    回复
  9. 9 F

    Wener

    2010-12-07 星期二 02:04

    那就是这样做的,把特定的分类加入到特定的导航栏位置。
    也不算特定,因为你就是那样设置的分类!~~~~

    回复
  10. 10 F

    微博博客

    2010-12-14 星期二 21:11

    我的也没有搞定,难啊!

    回复
  11. 11 F

    levin3d

    2011-01-07 星期五 00:35

    能不能帮我看看我这个模版怎么修改可以在下面的导航栏同时显示分类和页面!地址在这儿!

    回复
  12. 12 F

    路人甲

    2011-05-04 星期三 10:26

    调用,这段代码写在那个文件里面?是header.php里面吗?我的header.php里面只有的

    回复
  13. 13 F

    SEO是什么

    2011-09-30 星期五 10:50

    怎么用来拉取子目录做为对应分类的下拉菜单呢

    回复
  14. 14 F

    阿忠

    2011-11-27 星期天 02:20

    把代码复制进去后什么都没有了

    回复

添加评论