WordPress 3.0 导航菜单 (开发篇)

Jun 25th, 2010 Add Comment

WordPress 导航菜单的使用篇中, 已经介绍过 WP 3.0 导航菜单这一新功能. 在老版本的 WordPress 上, 页面列表和分类列表一直被用作导航菜单, 现在引入该功能, 我们应该怎样选择或者兼容两者呢? 本文将更加深入, 在代码层面继续发掘其更多特性. 在看到这些特性之后, 或许能勾起你的一些头绪.

关于导航菜单的使用方法, 请查看使用篇的介绍, 本文将侧重于主题开发.

用法

在主题调用导航菜单, 方法很简单. 只需加入以下语句在页面上输出菜单.

<?php wp_nav_menu(); ?>

但其实这个方法提供了很多可配置的参数, 下面我们逐一描述.

参数

参数列表来自 WordPress Codex, 下面逐一翻译, 并对不易理解的参数进行详细说明.

$menu
(字符串)(可选) 期望显示的菜单; 接受 (按顺序匹配的) id, slug, name
默认值: None

我们看一下 WordPress 取菜单的方法. 就像 Codex 上的描述一样, 它是按 id, slug, name 的顺序去取的.

function wp_get_nav_menu_object( $menu ) {
	// 没有提供参数, 返回空
	if ( ! $menu )
		return false;
 
	// 根据 id 找
	$menu_obj = get_term( $menu, 'nav_menu' );
 
	// 如果找不到, 根据 slug 来找
	if ( ! $menu_obj )
		$menu_obj = get_term_by( 'slug', $menu, 'nav_menu' );
 
	// 如果还找不到, 再根据 name 来找
	if ( ! $menu_obj )
		$menu_obj = get_term_by( 'name', $menu, 'nav_menu' );
 
	// 最终没找到, 返回空
	if ( ! $menu_obj )
		$menu_obj = false;
 
	return $menu_obj;
}

$container
(字符串)(可选) ul 父节点的标签类型
默认值: div

千万不要以为什么标签都可以使用, 事实上只有 div 和 nav 会被采用, 如果输入别的值, ul 父节点的标签将不会显示, 可见 Codex 的描述不够详尽. (从另一个角度看, WordPress 使用 nav 标签说明它正在提升对 HTML5 的支持力度.)

// 被允许使用的标签只有 div 和 nav
$allowed_tags = apply_filters( 'wp_nav_menu_container_allowedtags', array( 'div', 'nav' ) );

$container_class
(字符串)(可选) ul 父节点的 class 属性值
默认值: menu-{menu slug}-container

$container_id
(字符串)(可选) ul 父节点的 id 属性值
默认值: None

$menu_class
(字符串)(可选) ul 节点的 class 属性值
默认值: menu

$menu_id
(字符串)(可选) ul 节点的 id 属性值
默认值: menu slug, 自增长的

$echo
(布尔型)(可选) 决定直接显示菜单还是返回 HTML 片段
默认值: true (直接显示)

$fallback_cb
(字符串)(可选) 如果菜单不存在, 调用的回调函数
默认值: wp_page_menu (显示页面列表作为菜单)

这是一个很重要的方法, 可以通过它去兼容老版本主题. 下面我们看看代码. 关键是 $args 也被传入 call_user_func 中. 例如, 我们将参数 'sort_column'=>'menu_order' 写入 wp_nav_menu 的参数, 那它同样会被传到 call_user_func 方法中. 如果 call_user_func 是 wp_page_menu 方法, 那么显示的页面列表将以认为赋予的序号来排序输出.

// 如果找不到指定菜单, 或者菜单不存在任何条目并没有指定自定义菜单, 使用 call_user_func 方法来进行处理
if ( ( !$menu || is_wp_error($menu) || ( isset($menu_items) && empty($menu_items) && !$args->theme_location ) )
	&& ( function_exists($args->fallback_cb) || is_callable( $args->fallback_cb ) ) )
		return call_user_func( $args->fallback_cb, (array) $args );

$before
(字符串)(可选) 显示在每个菜单链接前的文本
默认值: None

$after
(字符串)(可选) 显示在每个菜单链接后的文本
默认值: None

$link_before
(字符串)(可选) 显示在每个菜单链接文本前的文本
默认值: None

$link_after
(字符串)(可选) 显示在每个菜单链接文本后的文本
默认值: None

我怀疑 Codex 对 $before 与 $link_before, $after 与 $link_after 的描述是不是倒过来了?

$depth
(整型)(可选) 显示菜单的深度, 当数值为 0 时显示所有
默认值: 0

$walker
(字符串)(可选) 自定义的遍历对象
默认值: None

$theme_locaton
(字符串)(可选) the location in the theme to be used--must be registered with register_nav_menu() in order to be selectable by the user
默认值: None

如果主题在 function.php 中登记了 3 个自定义菜单, 如下:

register_nav_menus(array('primary' => 'Primary Navigation'));
register_nav_menus(array('secondary' => 'Secondary Navigation'));
register_nav_menus(array('bottom' => 'Bottom Navigation'));

要调用 Secondary Navigation 这个导航菜单, 则可以在 header.php 文件里使用以下语句:

wp_nav_menu(array(
	'theme_location'	=>'secondary'
));

也就是说, 这是用来指定调用某个自定义菜单的.

我准备在所有发布的主题里添加对导航菜单的支持, 将会设计一套对老版本的兼容方案, 并以文章形式分享出来.
对于本文内容如有任何疑问和建议, 请在此留言.

声明: 本文采用 BY-NC-SA 协议进行授权. 转载请注明转自: WordPress 3.0 导航菜单 (开发篇)

  1. http://0.gravatar.com/avatar/23f97dfb5ddeacc339396a0d94059526?s=32&d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    如果在后台的菜单里没加任何东西,为何也会有首页之类的显示?

  2. http://0.gravatar.com/avatar/abe80b7bc1986be4e18d2ce924c8c8de?s=32&d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    自定义菜单能调用的只有默认分类,默认页面,能把自定义的分类和自定义的页面也加进去吗?

  3. http://0.gravatar.com/avatar/490cf262668eebb0f0f1a50d9d48d702?s=32&d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    @禾婉儿音乐部落格
    会有的. 快了~

    @Boolfish
    你在 A 博客做个接口提供博客导航信息, 在 B 博客中调用 A 博客的接口就可以了.

  4. http://1.gravatar.com/avatar/571551c043f153a315899086ad234b3d?s=32&d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    我想问一下,一个博客调用另一个博客上面的导航栏应该怎么调用?
    我试了开始调用这个require('../wp-blog-header.php' );
    然后再调用导航栏,但是都不行,显示的始终是第一个博客的导航栏...

  5. http://0.gravatar.com/avatar/4956c7fe81808f6e57e7c216f9c6870f?s=32&d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    一直在用你的主题。修改了一下,加上适合我网站的风格图片,真希望能用上3.0的主题。常逛你的站会学到很多有用的东西。

  6. http://1.gravatar.com/avatar/1cfd6b67e61a959b431aa1bc3e4f6736?s=32&d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    晕...好像代码被过滤了,转义一下再发。

    <!-- wp_nav_menu -->
    <div class="$container_class" id="$container_id">
        <ul class="$menu_class" id="$menu_id">
            <li>..</li>
            <li>..</li>
            ...
        </ul>
    <div>

    <!-- wp_page_menu -->
    <div class="$menu_class" id="$menu_id">
        <ul>
            <li>..</li>
            <li>..</li>
            ...
        </ul>
    <div>

  7. http://1.gravatar.com/avatar/1cfd6b67e61a959b431aa1bc3e4f6736?s=32&d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    发现一个问题,同样的参数 $menu_classwp_nav_menuwp_page_menu 里是不一样的。在前者里是 <ul> 元素的类名,后者里是外面的 wrapper 的类名,$menu_id 也是如此。

    wp_nav_menu 生成的是

    1
    2
    3
    4
    
     
    		..
    		..
    		...

    wp_page_menu 生成的是

    1
    2
    3
    4
    
     
    		..
    		..
    		...

    如果直接用 wp_page_menu 做 callback 会有问题。我现在只能用自己自定义的函数作为 callback 把参数意义修改得一致了。

  8. http://1.gravatar.com/avatar/3e0b0c8035b9c55ea69399026b500757?s=32&d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    回头好好试试!

  9. http://0.gravatar.com/avatar/490cf262668eebb0f0f1a50d9d48d702?s=32&d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    @老张博客
    如果你用传统的处理办法, 可以通过 orderby 来指定排序方法, 如果是使用 WordPress 3.0 的导航菜单, 那可以在后台面板中进行控制.

  10. http://1.gravatar.com/avatar/bf90f1504839fa07a72bb33a21c0932f?s=32&d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    不知道博主在不,向你请教一个关于导航菜单的问题,
    我是用分类做用导航菜单的,已生成导航菜单。但是我现在想调整他们在导航菜单里显示的顺序,需要怎么样才能实现呢。我的QQ:13156789

  11. http://0.gravatar.com/avatar/04bca3e5cd4a11ecb54521261e009aa0?s=32&d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    楼主的inove很不错.是否在3.0的基础上再次优化一下啊!!!

  12. http://1.gravatar.com/avatar/d809ee80197125bdba7ce0a157108b53?s=32&d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    ok testaooo mvui vao que vamo

  13. http://1.gravatar.com/avatar/737c91618baa5e1b69de1fd0f5f46730?s=32&d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    感觉没办法1次看懂呢= =

  14. http://1.gravatar.com/avatar/fa594097cda444a940420b6af8e0c5b3?s=32&d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    :cry: :cry: 中文还在更新,一直在等呢,半年了 :cry:

  15. http://0.gravatar.com/avatar/8ea3670f5230d5e6a0b95587cf25509e?s=32&d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    Mesele wordpress 3.0 değil yeğen, mesele neler yeni?

  16. http://0.gravatar.com/avatar/4dfbd693401458acb2f672f2c811fbc3?s=32&d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    台湾版早就出来了 简体中文的效率真低 (虽然有语言包)

  17. http://1.gravatar.com/avatar/78b0fd25b4aadfa50d9dde0ba2cc5d50?s=32&d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    这个更新对于做CMS来说效率大大提高了,先把享总这个文章收藏了慢慢研究……

  18. http://0.gravatar.com/avatar/4e561c83c0d5622273f176b110569d9b?s=32&d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    看不太懂,不过还是继续使用你的主题,不错

  19. http://0.gravatar.com/avatar/8fcd5cbe925db62a8a8adae5f74ba9ee?s=32&d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    我也感觉这次wordpress的更新不太好,3.0中的menu感觉用处不大,希望下个版本中能把menu给kill掉。

  20. http://1.gravatar.com/avatar/9ed94b19d58705577d8b6bf83653a97b?s=32&d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G
  21. http://1.gravatar.com/avatar/f1f44ed3050f869ebe4ebaac298fb7e3?s=32&d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    你好,请问你用的是什么主题?

  22. http://0.gravatar.com/avatar/8bc5a10d6cd90aec2d2e24b53042856f?s=32&d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    先留言,再看

  23. http://0.gravatar.com/avatar/2ce1c5c5226ee100d92c299de9ea4a0e?s=32&d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    中文正式版啥时出来咧,可以用用。

  24. http://1.gravatar.com/avatar/90d04faa49701e4e6e4225c4f29d595e?s=32&d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    目前发现兼容性最好的就是inove了

  25. http://1.gravatar.com/avatar/d4aa12519670fe291cdcfcae3aa792a4?s=32&d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    看不懂,但支持,现在用的就是您的主题

  26. http://0.gravatar.com/avatar/66a90bb0427b2ddd8366d21f96f17689?s=32&d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    用mg12大大的教程改mg12的模板……惭愧惭愧……

  27. http://1.gravatar.com/avatar/5fcd695fd32101de83d67b5bbc9d1f08?s=32&d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    向右移动一格就成为下级菜单,不知道PHP那里怎么控制输出,有子菜单的链接变成一个数组?是否mg12能写篇关于这方面的,不胜感激。

  28. http://0.gravatar.com/avatar/03487f19b54904dbf98f5ba4f10b04bb?s=32&d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    改主题去了~

  29. http://1.gravatar.com/avatar/7f611bafb05a2edc092fd476bb7b807d?s=32&d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    真的是看不懂,悲剧...

    感觉wp3.0有点晕,我还是继续用2.92版本的,不升级。

  30. http://0.gravatar.com/avatar/8eb05daeae832f4d0d5fa7dd5ff987dd?s=32&d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    wp 3.0我还没用,不过新主题的功能的确有可取之处。

  31. http://0.gravatar.com/avatar/490cf262668eebb0f0f1a50d9d48d702?s=32&d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    @bolo
    那一个数组传进去呗.

  32. http://0.gravatar.com/avatar/4c99f519d8e5f05a1218201c1b146fee?s=32&d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    让代码来的更纯粹一些吧~顶一个~

  33. http://1.gravatar.com/avatar/fd126aa64db6755fe66749e7870b9c9c?s=32&d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    太麻烦了,直接在header.php添加代码多方便

  34. http://0.gravatar.com/avatar/a0ebb3f38297334954dca242ae92b563?s=32&d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    不怎么懂代码,过来看看~~~ :|

  35. http://0.gravatar.com/avatar/2a9c4f525050372a6fe0b10ce4fe8957?s=32&d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    既然 register_nav_menus 的参数是一个 array ,那不能把三个菜单都通过一次函数调用进行注册?
    PS:哥还没时间去看 codex 呢,你就翻译了,我就改主题去了

  36. http://0.gravatar.com/avatar/490cf262668eebb0f0f1a50d9d48d702?s=32&d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    @③秋之流☆
    最近你抢沙发很强大.

    @ZiYo
    不会吧, 我只是在翻译 codex 的基础上加了进一步解说而已. 呵呵~

    @Valentine Belonwu
    Maybe, but I will update my themes and plugins so that they can works better.

    @纳粹
    兼容的.

  37. http://1.gravatar.com/avatar/7c9f43aa567f5fa7ae5b99c37a243da4?s=32&d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    呃,那贵主题和3.0兼容否?

  38. http://1.gravatar.com/avatar/b13335a1aa555def474d583022125c89?s=32&d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    I didn't like the wordpress 3.0 because it lacks some fetures, I switched to wordpress 3.0 before but it gave me some problems and i decided to switched back to my old wordpress.

  39. http://0.gravatar.com/avatar/01b84b6c5ee894b70fd7358e7a238064?s=32&d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    太深了,看不懂,纯支持:)

  40. http://0.gravatar.com/avatar/aad3b4423e897b2fd2647ee77a56a965?s=32&d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G

    我还是沙发...坐下来慢慢看... :|

  1. Loading...