按照我们的习惯(或者只是我个人的习惯),习惯了在网页的上方显示导航菜单。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基础就应该怎么添加。

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