WordPress 3.0 自定义导航菜单

WordPresss 3.0 的亮点之一就是引入了一个全新的导航菜单系统:menus。这一系统可能比它提供的多站点功能(MultiSite)更让使用者们兴奋。因为一直以来都有很多人苦恼于个性化导航菜单的设计不易,各种主题提供的解决方案不能满足要求,虽然有大量专门的插件却难于配置。同时又因为没有统一的标准,当我们想享受 WordPress 的不同主题的时候,一系列关于导航菜单的问题就会让人抓破脑袋。今天就让我们一起来领略一下 WordPress 3.0 的自定义菜单功能的简易与强大。

下面是一位主题开发人员,Justin Tadlock,写的介绍 WordPress 3.0 引入的 menus 导航菜单的文章,我觉得很不错,就给翻译出来与大家分享。该文同时介绍了作为一个主题开发者可以如何将 WordPress 3.0 的这一特性集成到主题中去。

一、Menus系统特性

在WordPress 3.0中,你将会在管理控制面板的 Appearance(外观) 菜单下见到一个被称为 Menus 的菜单系统。下图展示了该页面的 4 个主要元素。

  • 菜单位置 Theme Locations: 如果你的主题支持导航菜单功能,它会提供一个位置让你可以添加自定义菜单。在这里可以定义每个菜单在主题中的位置。
  • 菜单列表 Individual Menus: 这里显示的是你的菜单名称,一旦你创建了一个菜单,它的名称就出现在这里。(只要单击后面的“+”号就能创建一个新菜单。)
  • 增加菜单条目:这里列出了几个包含静态页面、其它文章类型、分类、其它分类系统、自定义链接等的选择框,你可以从中选择要加入到自定义菜单的条目。
  • 菜单条目:一旦你增加了条目到你的菜单系统中,它们就会出现在这里,你可以从这里配置条目的属性。
WordPress 菜单页面布局及功能介绍

WordPress 菜单页面布局及功能介绍

每个菜单条目都有它自己的配置选项。添加了条目之后,你就可以打开它,对其属性(这些属性在 WordPress 3.1 中进行了调整,请参考后面的留言)进行编辑。

  • URL(链接)
  • Navigation Label(导航标签)
  • Title Attribute(标题属性)
  • CSS Classes(CSS类)
  • Link Relationship (XFN,链接关系)
  • Description(描述)
  • Link Target(链接目标,即链接打开方式,也就是指定该链接是在当前窗口/标签页打开,还是在一个新的浏览器窗口/标签页打开。另外,Please note that a kitten dies every time a link is opened in a new window/tab.(实在对不住,这句不知道怎么译。来自 snowfox373补充说明:例如你把 target 设置为 _self,但是打开的时候使用了浏览器的命令,那么浏览器命令会优先于网页代码中的设置。你使用了鼠标手势或者右键-在新窗口中打开,那么该链接不会在本页跳转打开,而是在新的窗口或者空白页打开。))
配置 WordPress 菜单条目属性

配置 WordPress 菜单条目属性

高级属性如下:

Menus 链接高级属性

Menus 链接高级属性

二、在主题中注册一个菜单

也就是说,设置主题中不同位置处的菜单。

要将某个特定的菜单添加到主题中的某个位置,需要将该菜单登记进去。否则,我们就不知道哪个菜单应该在哪个位置上出现。该函数有两种使用方式(注意有一个 s 的区别):

  • register_nav_menu(): 注册一个单一的菜单位置。
  • register_nav_menus(): 注册多个菜单位置。

在下面的例子中,我们将在主题的 functions.php 函数中注册一个称为 Primary Menu 的菜单

add_action( 'init', 'register_my_menu' ); 
function register_my_menu() {
     register_nav_menu( 'primary-menu', __( 'Primary Menu' ) ); 
}

“primary-menu” 是我们在代码中用于标识该菜单的别名。“Primary Menu” 是我们在控制面板中用于标识该菜单的标签。

当然,我们也可以利用类似的方式注册多个菜单。

add_action( 'init', 'register_my_menus' ); 
function register_my_menus() { 
    register_nav_menus( 
        array( 
            'primary-menu' => __( 'Primary Menu' ), 
            'secondary-menu' => __( 'Secondary Menu' ), 
            'tertiary-menu' => __( 'Tertiary Menu' ) 
        ) 
    ); 
}

三、显示一个导航菜单

有两种方式可用于显示一个导航菜单。一种是在主题模板中调用 wp_nav_menu() 函数,另一种是使用 Navigation Menu 小工具。

在主题模板中显示一个菜单

大多数主题都会在 header.php 模板中调用一个导航栏,但是MENUS能够放在主题的任何位置。调用自定义导航菜单的最简单形式为:

<?php wp_nav_menu(); ?>

该语句将会加载用户创建的菜单或者如果导航菜单不存在的话就调用一个标准的页面列表。

我们可能想对这个调用进行更多的控制。如果从前面提到的 Primary Menu 来调用一个导航菜单,可以这么做:

<?php wp_nav_menu( array( 'theme_location' => 'primary-menu' ) ); ?>

你还可以拥有更多的控制权。wp_nav_menu() 函数有几个参数,可以用来对将要显示的菜单进行控制:

  • theme_location: 调用一个与特定的主题位置相关联的菜单。
  • menu: 调用指定 ID、别名或名称的菜单。
  • container: 封装该菜单的元素。默认是 div,但是如果你使用 HTML 5 的话,你也可以改为 nav。
  • container_class: 封装元素的 CSS 类(指定其显示样式)。
  • menu_class: 指定无序列表的 CSS 类,默认是 menu。
  • fallback_cb: 指定不存在菜单项目时要调用的函数。默认情况下会调用wp_list_pages() 函数(WordPress 的静态页面列表)。
  • before: 要显示在链接文字之前的文字(也是链接的一部分)。
  • after: 要显示在链接文字之后的文字(也是链接的一部分)。
  • link_before: 要显示在链接前面的文字(不是链接的一部分)。
  • link_after: 要显示在链接后面的文字(不是链接的一部分)。
  • depth: 指定显示菜单的层次深度,这在定义下拉式菜单的比较有用。默认情况是0(所有层次)。
  • walker: 允许自定义一个 walker(巡游?)PHP 类来创建菜单。
  • echo: 定义是显示该菜单还是仅仅返回数据供PHP程序使用。默认是真,直接显示该菜单。

使用导航菜单微件显示一个菜单

默认情况下,WordPress 提供了一个简单的菜单微件让我们能够显示选择任何自定义的菜单。你需要的仅仅是一个支持微件的主题(似乎一般的主题都支持微件的吧)。这项使用很简单,就不多介绍了。

四、为导航菜单设定样式

这里无法完全教会您如何给一个菜单编写样式,那需要一个完整的 CSS 教程才能完成。但是一般情况下我们只需要对已有的样式进行修改即可,所以这里给出一些技巧,帮助您修改菜单的 CSS 样式。

哪里有菜单样式可用?其实很简单。首先,很多主题都已经自带了菜单的样式。其次,如果您看到某个页面上的菜单样式很好看,可以右键单击该页面,选择“查看源文件”,然后找到(可以搜索,Ctrl+F)style.css文件并下载下来就知道它用的是什么样的样式了。

下面让我们来看看一些简单的技巧:

使用 current-menu-item class(CSS类)可以设定当前正在浏览的菜单条目的样式。它让您能够高亮选中读者当前正在浏览的页面对应的导航栏条目。下面是一个示例:

#primary-menu li.current-menu-item a { 
    background: #fff url(images/primary-menu-active.png) repeat-x 0 0; 
    border-top: none; 
    border-bottom: 2px solid #fff; 
}

您可以用一个很可靠的插件 Superfish jQuery 作为基础来实现一些很炫的效果。它提供一些细微但很酷的 JavaScript 功能,还能够修正菜单在 Internet Explorer 6 中的下拉问题而不需要再去采取别的手段。

到这里,你应该已经了解到处理 WordPress 中的自定义导航菜单的各方面内容了。不过,下面还有一些更深层次的技巧,也许你也想了解一下。

五、一些有用的相关函数

回调默认导航菜单

假设你希望用户加入条目后该菜单才显示出来。该特性让我们可以使用很多的布局方式。下面的说明让你能够支持最多4种布局方式。

这种设置的关键在于确保系统不会因为没有检测到 memus 而调用默认的菜单。下面以前面创建的主菜单 (Primary Menu) 为例进行说明。

<?php 
wp_nav_menu( 
    array( 
        'theme_location' => 'primary-menu', 
        'fallback_cb'    => '' 
    ) 
); 
?>

上面的代码告诉 WordPress,我们不希望 WordPress 因为用户没有给菜单添加条目(因而该菜单不会显示)而被回调到任何别的菜单(WordPress 默认情况下可能会调用默认的菜单,是不是它觉得你总该有个菜单吧:-))。

检查某个主题位置是否存在一个菜单

WordPress 提供了一个条件函数 has_nav_menu() 来检查特定主题位置是否存在一个菜单。假设我们创建了一个容器,其中包含了一个菜单和一个搜索框。但是,如果没有为该位置定义菜单,我们希望这两个东西都不显示出来。也就是说,让这两样东西要么同时出现,要么都不出现。

当你在某个主题位置调用一个菜单时,可以先检查是否有菜单关联到该位置。注意,下面的例子中我们使用菜单别名而不是名称或者ID来进行判断。

<?php if ( has_nav_menu( 'primary-menu' ) ) { ?> 
    <div class="nav-container"> 
        <?php wp_nav_menu( array( 'theme_location' => 'primary-menu' ) ); ?> 
        <?php get_search_form(); ?> 
    </div> 
} ?>

允许更多地菜单容器标签

默认的菜单系统只允许使用 <div> 和 <nav> 作为菜单容器。这能满足大多数需要。但是,如果因为某些原因,你需要使用别的容器来包含菜单,你可以使用下面的代码来实现。

add_filter( 'wp_nav_menu_container_allowedtags', 'my_menu_allowed_tags' ); 
function my_menu_allowed_tags( $tags ) { 
    $tags[] = 'p'; 
    return $tags; 
}

请注意,这里的 <p> 标签仅仅是个例子,实际上一般不会使用这样的标签来包含一个菜单。

获取所有主题位置列表

如果你需要列出主题中所有的菜单位置,需要使用下面的函数。该函数返回一个包含所有位置的数组。

$locations = get_nav_menu_locations();

创建一个菜单

多数主题开发者应该不会使用这样的函数,但是也可能会有需要它的地方。大多数情况下,我们应该使用主题位置定义函数(register_nav_menu())而不是这个函数。但是,如果你需要通过程序来控制一个菜单的创建,就需要使用 wp_create_nav_menu() 函数了。

wp_create_nav_menu( 'Menu Name', array( 'slug' => 'menu-slug' ) );

检查指定的菜单是否存在

这个函数对主题开发人员可能没什么用,但是迟早还是会用到的。它让你能够通过ID、名称或别名来检查特定的菜单是否存在。

if ( is_nav_menu( 'menu-slug' ) )
    /* 如果该菜单存在则执行…… */
else
    /* 如果该菜单不存在就执行…… */

原文链接:http://justintadlock.com/archives/2010/06/01/goodbye-headaches-hello-menus

翻译:水景一页

如果您使用中有任何问题,欢迎留言,我会尽力给您提供帮助。或者您也可以到讨论区的相应版块提问,我会第一时间给您答复。©

本文发表于水景一页。永久链接:<https://cnzhx.net/blog/wordpress-3-0-menus/>。转载请保留此信息及相应链接。

37 条关于 “WordPress 3.0 自定义导航菜单” 的评论

  1. 你的博客导航栏和我用的主题差不多上面只有一栏,如果在这栏里面放 “首页”“ 地图”这样的页面就放不了 分类目录了,反之如果放了分类就放不了页面了。请问你的博客如何在页面的下拉列表里面出现分类的,用的什么插件,谢谢。

    • 元宵节快乐!
      我这个没有用插件,就在后台——>外观——>目录(Menus)里设置的时候将分类建了一栏,然后将需要的分类从左边的“分类”里面添加到“目录”,并将它们都作为这一栏的二级菜单(左键拖着往右拉一点就行了)。但是这个也许需要你的主题支持。

  2. 我,添加的类别和自定义链接的设置属性少了三个,只有导航标签和标题属性,另外三个属性未显示出来,不知道该如何解决?
    我已经将主题和wp-config.php之外的文件用官方下载的替换过了,主题也换过,是不是可以定位wp-config.php的问题?可是我与wp-config-sample.php对比过了,除了一些账号密码等被改其他的都是一样的呃,不知道为什么会出现这样的问题,还望大侠能指点迷津,谢谢.

    • 刚才仔细看了下,在“菜单”的设定页面右上角的“显示选项”那里可以打开高级属性,这样就有你说的另外三个了。
      这应该是新版本的改动,还真没注意到。

  3. 引用通告: WordPress 3.0 自定义导航菜单的实现 - 智能软件工作室 ,flash网站模板,昆明网站建设,软件开发

  4. 引用通告: 解决WordPress错误:Warning: Cannot modify header information | 忘川彼岸

  5. Please note that a kitten dies every time a link is opened in a new window/tab.
    需要注意的是,每次在新窗口或者新标签页打开链接的时候,该属性是无效的。
    该句式为:every time do sth. a kitten dies.也可以是every time do sth. god kills a kitten.意为出问题,没效果等,没有准确的翻译,总之看实际情况,意会就好。

    • 谢谢!大意就是这样,因为 kitten 这词不知道什么意思所以就没法翻了。
      不过经您提醒,我应该在那里做个注释,说明这个选项含义的。

  6. 补充说明:例如你把target设置为_self,但是打开的时候使用了浏览器的命令,那么浏览器命令会优先于网页代码中的设置。你使用了鼠标手势或者右键-在新窗口中打开,那么该链接不会在本页跳转打开,而是在新的窗口或者空白页打开。

    • 嗯,很方便,尤其是针对那些需要独立起来的“文章分类”。只是就不能与主博客共享标签了,连作者链接都出现了多个。

      • 我觉得不使用MU也很方便,只是要添加很多判定。一样能够实现这些功能。

        • 嗯,所以我只是将特别需要独立的分出去了,添加判定的话,可移植性就不强了,不方便。

          • 我正在纠结先洗澡还是先夜宵,先去洗澡吧还是。
            回头再聊。
            都当成IM了。

            • 我正想说这事儿呢,回头聊的话还是去我的论坛吧,我们在这里离题太远了。

          • 顺便说下你也许可以考虑把日期显示格式修改一下。五月 7, 2011 周六 at 10:46 下午 这样子确实怪异。

  7. 另外K2主题的顶部nav在IE浏览器的高分辨率(宽度大于1024)下是会错位的。

  8. 引用通告: WordPress 3.0 自定义导航菜单[使用规则和编码方式] | WordPress一站式服务

  9. 引用通告: WordPress:条件控制小工具插件 | 水景一页

时间过去太久,评论已关闭。
如果您有话要说,请到讨论区留言并给出此文章链接。
谢谢您的理解 :-)