WordPress中制作导航菜单的PHP核心方法讲解
<p>wordpress 3.0 引入导航菜单功能, 让页面的导航和链接的管理变得简单易用. wp 向用户提供了菜单管理页面和多种调用方法, 我们先来看一下一般wordpress 的导航菜单都具有哪些功能.</p>
<p>
<br><strong>管理菜单页面</strong></p>
<p>
页面路径: appearance > menus<br>
由从界面来看, 能够创建多个菜单, 并且可以向菜单中添加自定义链接, 页面链接和分类链接.</p>
<p>
<img style="max-width:100%!important;height:auto!important;"title="WordPress中制作导航菜单的PHP核心方法讲解" alt="WordPress中制作导航菜单的PHP核心方法讲解" src="https://zhuji.jb51.net/uploads/img/202305/1cb251bfec8912325462eb7b6ff73c03.jpg"></p>
<p>
但有一点需要注意, 如果将页面链接和分类链接加入, 被带入菜单的仅是链接, 而不是页面和分类本身, 也就是说, 子页面和子分类不会成为菜单的一部分.</p>
<p>
另外, 我们也不能在菜单中加入别的菜单, 所以这种自定义的菜单注定只存在一级. 在右边排列菜单区块中, 只要将某个菜单往右移一格, 就可以作为下级菜单. 所以是可以创建多级的.<br>
创建菜单后, 我们就可以通过在 widgets 页面将这些菜单添加到侧边栏上了.</p>
<p>
<img style="max-width:100%!important;height:auto!important;"title="WordPress中制作导航菜单的PHP核心方法讲解" alt="WordPress中制作导航菜单的PHP核心方法讲解" src="https://zhuji.jb51.net/uploads/img/202305/c53a2aeabc2d762a66c10c6a81a92e46.jpg"></p>
<p>
<strong>登记自定义菜单</strong></p>
<p>
在菜单管理页面中注意到 theme locations 区块提示如下:</p>
<div>
<div>
<div id="highlighter_788968">
<div>
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td>
<div>
1</div>
</td>
<td>
<div>
<div>
<code>the current theme does not natively support menus, but you can </code><code>use</code> <code>the </code><code>"custom menu"</code> <code>widget to add any menus you create here to the theme's sidebar.</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
</div>
<p>
意思是说, 现在你的主题不支持自定义菜单, 但可以通过 widget 的方式将自定义加到主题的侧边栏. 那如何让主题也能支持自定义菜单呢? 请将以下代码加到 function.php 中.</p>
<div>
<div>
<div id="highlighter_450175">
<div>
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td>
<div>
1</div>
<div>
2</div>
<div>
3</div>
</td>
<td>
<div>
<div>
<code>register_nav_menus(</code><code>array</code><code>(</code>
</div>
<div>
<code> </code><code>'primary'</code> <code>=> </code><code>'primary navigation'</code>
</div>
<div>
<code>));</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
</div>
<p>
这段代码用于记录一个自定义菜单, 你可以为它选择具体的应用菜单, 其中 primary 应是唯一识别符, primary navigation 是菜单的名称. 可以通过这个函数为主题添加多个自定义菜单. 如果在 function.php 添加登记方法如下:</p>
<div>
<div>
<div id="highlighter_435167">
<div>
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td>
<div>
1</div>
<div>
2</div>
<div>
3</div>
</td>
<td>
<div>
<div>
<code>register_nav_menus(</code><code>array</code><code>(</code><code>'primary'</code> <code>=> </code><code>'primary navigation'</code><code>));</code>
</div>
<div>
<code>register_nav_menus(</code><code>array</code><code>(</code><code>'secondary'</code> <code>=> </code><code>'secondary navigation'</code><code>));</code>
</div>
<div>
<code>register_nav_menus(</code><code>array</code><code>(</code><code>'bottom'</code> <code>=> </code><code>'bottom navigation'</code><code>));</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
</div>
<p>
在菜单管理页面将会看到如下图的内容.</p>
<p>
<img style="max-width:100%!important;height:auto!important;"title="WordPress中制作导航菜单的PHP核心方法讲解" alt="WordPress中制作导航菜单的PHP核心方法讲解" src="https://zhuji.jb51.net/uploads/img/202305/2bb0e07b99405babcf1681982eb77602.jpg"></p>
<p>
<strong>主题调用菜单</strong></p>
<p>
在主题中如何调用菜单呢? 在主题的适合位置使用方法 wp_nav_menu();, 向页面输出菜单.<br>
方法中提供参数 theme_location, 用于指定对应的自定义菜单. 如要调用第一个菜单, 则代码如下:</p>
<div>
<div>
<div id="highlighter_751549">
<div>
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td>
<div>
1</div>
<div>
2</div>
<div>
3</div>
</td>
<td>
<div>
<div>
<code>wp_nav_menu(</code><code>array</code><code>(</code>
</div>
<div>
<code> </code><code>'theme_location'</code> <code>=></code><code>'primary'</code>
</div>
<div>
<code>));</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
</div>
<p>
在默认情况下如果没有定义任何菜单, 使用 wp_nav_menu 方法与 wp_list_pages (调用页面列表) 方法无异, 但效率不及后者. 所以, 如果你准备用页面列表或者分类列表作为导航菜单, 建议不要使用 wp_nav_menu.</p>
<p>
<strong>用法</strong></p>
<p>
在主题调用导航菜单, 方法很简单. 只需加入以下语句在页面上输出菜单.</p>
<div>
<div>
<div id="highlighter_730012">
<div>
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td>
<div>
1</div>
</td>
<td>
<div>
<div>
<code><?php wp_nav_menu(); ?></code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
</div>
<p>
但其实这个方法提供了很多可配置的参数, 下面我们逐一描述.</p>
<p>
<strong>参数</strong></p>
<p>
参数列表来自 wordpress codex, 下面逐一翻译, 并对不易理解的参数进行详细说明.</p>
<p>
<strong>$menu</strong><br>
(字符串)(可选) 期望显示的菜单; 接受 (按顺序匹配的) id, slug, name<br>
默认值: none</p>
<p>
我们看一下 wordpress 取菜单的方法. 就像 codex 上的描述一样, 它是按 id, slug, name 的顺序去取的.</p>
<div>
<div>
<div id="highlighter_224149">
<div>
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td>
<div>
1</div>
<div>
2</div>
<div>
3</div>
<div>
4</div>
<div>
5</div>
<div>
6</div>
<div>
7</div>
<div>
8</div>
<div>
9</div>
<div>
10</div>
<div>
11</div>
<div>
12</div>
<div>
13</div>
<div>
14</div>
<div>
15</div>
<div>
16</div>
<div>
17</div>
<div>
18</div>
<div>
19</div>
<div>
20</div>
<div>
21</div>
<div>
22</div>
</td>
<td>
<div>
<div>
<code>function</code> <code>wp_get_nav_menu_object( </code><code>$menu</code> <code>) {</code>
</div>
<div>
<code> </code><code>// 没有提供参数, 返回空</code>
</div>
<div>
<code> </code><code>if</code> <code>( ! </code><code>$menu</code> <code>)</code>
</div>
<div>
<code> </code><code>return</code> <code>false;</code>
</div>
<div>
<code> </code>
</div>
<div>
<code> </code><code>// 根据 id 找</code>
</div>
<div>
<code> </code><code>$menu_obj</code> <code>= get_term( </code><code>$menu</code><code>, </code><code>'nav_menu'</code> <code>);</code>
</div>
<div>
<code> </code>
</div>
<div>
<code> </code><code>// 如果找不到, 根据 slug 来找</code>
</div>
<div>
<code> </code><code>if</code> <code>( ! </code><code>$menu_obj</code> <code>)</code>
</div>
<div>
<code> </code><code>$menu_obj</code> <code>= get_term_by( </code><code>'slug'</code><code>, </code><code>$menu</code><code>, </code><code>'nav_menu'</code> <code>);</code>
</div>
<div>
<code> </code>
</div>
<div>
<code> </code><code>// 如果还找不到, 再根据 name 来找</code>
</div>
<div>
<code> </code><code>if</code> <code>( ! </code><code>$menu_obj</code> <code>)</code>
</div>
<div>
<code> </code><code>$menu_obj</code> <code>= get_term_by( </code><code>'name'</code><code>, </code><code>$menu</code><code>, </code><code>'nav_menu'</code> <code>);</code>
</div>
<div>
<code> </code>
</div>
<div>
<code> </code><code>// 最终没找到, 返回空</code>
</div>
<div>
<code> </code><code>if</code> <code>( ! </code><code>$menu_obj</code> <code>)</code>
</div>
<div>
<code> </code><code>$menu_obj</code> <code>= false;</code>
</div>
<div>
<code> </code>
</div>
<div>
<code> </code><code>return</code> <code>$menu_obj</code><code>;</code>
</div>
<div>
<code>}</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
</div>
<p>
<strong>$container</strong><br>
(字符串)(可选) ul 父节点的标签类型<br>
默认值: div</p>
<p>
千万不要以为什么标签都可以使用, 事实上只有 div 和 nav 会被采用, 如果输入别的值, ul 父节点的标签将不会显示, 可见 codex 的描述不够详尽. (从另一个角度看, wordpress 使用 nav 标签说明它正在提升对 html5 的支持力度.)</p>
<div>
<div>
<div id="highlighter_873786">
<div>
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td>
<div>
1</div>
<div>
2</div>
</td>
<td>
<div>
<div>
<code>// 被允许使用的标签只有 div 和 nav</code>
</div>
<div>
<code>$allowed_tags</code> <code>= apply_filters( </code><code>'wp_nav_menu_container_allowedtags'</code><code>, </code><code>array</code><code>( </code><code>'div'</code><code>, </code><code>'nav'</code> <code>) );</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
</div>
<p>
<strong>$container_class</strong><br>
(字符串)(可选) ul 父节点的 class 属性值<br>
默认值: menu-{menu slug}-container</p>
<p>
<strong>$container_id</strong><br>
(字符串)(可选) ul 父节点的 id 属性值<br>
默认值: none</p>
<p>
<strong>$menu_class</strong><br>
(字符串)(可选) ul 节点的 class 属性值<br>
默认值: menu</p>
<p>
<strong>$menu_id</strong><br>
(字符串)(可选) ul 节点的 id 属性值<br>
默认值: menu slug, 自增长的</p>
<p>
<strong>$echo</strong><br>
(布尔型)(可选) 决定直接显示菜单还是返回 html 片段<br>
默认值: true (直接显示)</p>
<p>
<strong>$fallback_cb</strong><br>
(字符串)(可选) 如果菜单不存在, 调用的回调函数<br>
默认值: wp_page_menu (显示页面列表作为菜单)</p>
<p>
这是一个很重要的方法, 可以通过它去兼容老版本主题. 下面我们看看代码. 关键是 $args 也被传入 call_user_func 中. 例如, 我们将参数 'sort_column'=>'menu_order' 写入 wp_nav_menu 的参数, 那它同样会被传到 call_user_func 方法中. 如果 call_user_func 是 wp_page_menu 方法, 那么显示的页面列表将以认为赋予的序号来排序输出.</p>
<div>
<div>
<div id="highlighter_126657">
<div>
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td>
<div>
1</div>
<div>
2</div>
<div>
3</div>
<div>
4</div>
</td>
<td>
<div>
<div>
<code>// 如果找不到指定菜单, 或者菜单不存在任何条目并没有指定自定义菜单, 使用 call_user_func 方法来进行处理</code>
</div>
<div>
<code>if</code> <code>( ( !</code><code>$menu</code> <code>|| is_wp_error(</code><code>$menu</code><code>) || ( isset(</code><code>$menu_items</code><code>) && </code><code>empty</code><code>(</code><code>$menu_items</code><code>) && !</code><code>$args</code><code>->theme_location ) )</code>
</div>
<div>
<code> </code><code>&& ( function_exists(</code><code>$args</code><code>->fallback_cb) || </code><code>is_callable</code><code>( </code><code>$args</code><code>->fallback_cb ) ) )</code>
</div>
<div>
<code> </code><code>return</code> <code>call_user_func( </code><code>$args</code><code>->fallback_cb, (</code><code>array</code><code>) </code><code>$args</code> <code>);</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
</div>
<p>
<strong>$before</strong><br>
(字符串)(可选) 显示在每个菜单链接前的文本<br>
默认值: none</p>
<p>
<strong>$after</strong><br>
(字符串)(可选) 显示在每个菜单链接后的文本<br>
默认值: none</p>
<p>
<strong>$link_before</strong><br>
(字符串)(可选) 显示在每个菜单链接文本前的文本<br>
默认值: none</p>
<p>
<strong>$link_after</strong><br>
(字符串)(可选) 显示在每个菜单链接文本后的文本<br>
默认值: none</p>
<p>
我怀疑 codex 对 $before 与 $link_before, $after 与 $link_after 的描述是不是倒过来了?</p>
<p>
<strong>$depth</strong><br>
(整型)(可选) 显示菜单的深度, 当数值为 0 时显示所有<br>
默认值: 0</p>
<p>
<strong>$walker</strong><br>
(字符串)(可选) 自定义的遍历对象<br>
默认值: none</p>
<p>
<strong>$theme_locaton</strong><br>
(字符串)(可选) the location in the theme to be used--must be registered with register_nav_menu() in order to be selectable by the user<br>
默认值: none</p>
<p>
如果主题在 function.php 中登记了 3 个自定义菜单, 如下:</p>
<div>
<div>
<div id="highlighter_771375">
<div>
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td>
<div>
1</div>
<div>
2</div>
<div>
3</div>
</td>
<td>
<div>
<div>
<code>register_nav_menus(</code><code>array</code><code>(</code><code>'primary'</code> <code>=> </code><code>'primary navigation'</code><code>));</code>
</div>
<div>
<code>register_nav_menus(</code><code>array</code><code>(</code><code>'secondary'</code> <code>=> </code><code>'secondary navigation'</code><code>));</code>
</div>
<div>
<code>register_nav_menus(</code><code>array</code><code>(</code><code>'bottom'</code> <code>=> </code><code>'bottom navigation'</code><code>));</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
</div>
<p>
要调用 secondary navigation 这个导航菜单, 则可以在 header.php 文件里使用以下语句:</p>
<div>
<div>
<div id="highlighter_899402">
<div>
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td>
<div>
1</div>
<div>
2</div>
<div>
3</div>
</td>
<td>
<div>
<div>
<code>wp_nav_menu(</code><code>array</code><code>(</code>
</div>
<div>
<code> </code><code>'theme_location'</code> <code>=></code><code>'secondary'</code>
</div>
<div>
<code>));</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
</div>
<p>
也就是说, 这是用来指定调用某个自定义菜单的.</p>
頁:
[1]