WordPress 3.0 导航菜单 (开发篇)
在 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' ));
也就是说, 这是用来指定调用某个自定义菜单的.
我准备在所有发布的主题里添加对导航菜单的支持, 将会设计一套对老版本的兼容方案, 并以文章形式分享出来.
对于本文内容如有任何疑问和建议, 请在此留言.
如果在后台的菜单里没加任何东西,为何也会有首页之类的显示?
自定义菜单能调用的只有默认分类,默认页面,能把自定义的分类和自定义的页面也加进去吗?
@禾婉儿音乐部落格
会有的. 快了~
@Boolfish
你在 A 博客做个接口提供博客导航信息, 在 B 博客中调用 A 博客的接口就可以了.
我想问一下,一个博客调用另一个博客上面的导航栏应该怎么调用?
我试了开始调用这个require('../wp-blog-header.php' );
然后再调用导航栏,但是都不行,显示的始终是第一个博客的导航栏...
一直在用你的主题。修改了一下,加上适合我网站的风格图片,真希望能用上3.0的主题。常逛你的站会学到很多有用的东西。
晕...好像代码被过滤了,转义一下再发。
<!-- 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>
发现一个问题,同样的参数
$menu_class在wp_nav_menu和wp_page_menu里是不一样的。在前者里是<ul>元素的类名,后者里是外面的 wrapper 的类名,$menu_id也是如此。wp_nav_menu生成的是wp_page_menu生成的是如果直接用
wp_page_menu做 callback 会有问题。我现在只能用自己自定义的函数作为 callback 把参数意义修改得一致了。回头好好试试!
@老张博客
如果你用传统的处理办法, 可以通过 orderby 来指定排序方法, 如果是使用 WordPress 3.0 的导航菜单, 那可以在后台面板中进行控制.
不知道博主在不,向你请教一个关于导航菜单的问题,
我是用分类做用导航菜单的,已生成导航菜单。但是我现在想调整他们在导航菜单里显示的顺序,需要怎么样才能实现呢。我的QQ:13156789
楼主的inove很不错.是否在3.0的基础上再次优化一下啊!!!
ok testaooo mvui vao que vamo
感觉没办法1次看懂呢= =
Mesele wordpress 3.0 değil yeğen, mesele neler yeni?
台湾版早就出来了 简体中文的效率真低 (虽然有语言包)
这个更新对于做CMS来说效率大大提高了,先把享总这个文章收藏了慢慢研究……
看不太懂,不过还是继续使用你的主题,不错
我也感觉这次wordpress的更新不太好,3.0中的menu感觉用处不大,希望下个版本中能把menu给kill掉。
lagi..
你好,请问你用的是什么主题?
先留言,再看
中文正式版啥时出来咧,可以用用。
目前发现兼容性最好的就是inove了
看不懂,但支持,现在用的就是您的主题
用mg12大大的教程改mg12的模板……惭愧惭愧……
向右移动一格就成为下级菜单,不知道PHP那里怎么控制输出,有子菜单的链接变成一个数组?是否mg12能写篇关于这方面的,不胜感激。
改主题去了~
真的是看不懂,悲剧...
感觉wp3.0有点晕,我还是继续用2.92版本的,不升级。
wp 3.0我还没用,不过新主题的功能的确有可取之处。
@bolo
那一个数组传进去呗.
让代码来的更纯粹一些吧~顶一个~
太麻烦了,直接在header.php添加代码多方便
不怎么懂代码,过来看看~~~
既然 register_nav_menus 的参数是一个 array ,那不能把三个菜单都通过一次函数调用进行注册?
PS:哥还没时间去看 codex 呢,你就翻译了,我就改主题去了
@③秋之流☆
最近你抢沙发很强大.
@ZiYo
不会吧, 我只是在翻译 codex 的基础上加了进一步解说而已. 呵呵~
@Valentine Belonwu
Maybe, but I will update my themes and plugins so that they can works better.
@纳粹
兼容的.
呃,那贵主题和3.0兼容否?
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.
太深了,看不懂,纯支持:)
我还是沙发...坐下来慢慢看...