在不使用插件的情况下在 WordPress 中创建自定义导航菜单
已发表: 2020-11-28无论您使用什么 WordPress 主题,它几乎肯定会提供至少一个菜单位置,您可以在其中显示您的菜单(通常在您的网站标题中)。 可以从管理区域内轻松创建菜单并快速添加到这些预设位置。 但是,如果您需要在网站的其他地方显示另一个菜单,您会怎么做? 在本教程中,我们将了解如何创建自己的导航菜单,该菜单可以显示在您选择的位置,而无需使用插件。
我们走吧!
注册您的新自定义菜单位置
我们需要做的第一件事是注册新的自定义菜单的位置。 为此,请使用您选择的文本编辑器(如 Sublime)打开活动主题的 functions.php 文件并添加以下代码:
function my_custom_menu() { register_nav_menu('my-custom-menu',__( 'My Custom Menu' )); } add_action( 'init', 'my_custom_menu' );
在这段代码中,我们使用了add_action()
钩子来添加回调函数my_custom_menu()
。 这意味着my_custom_menu()
函数将与每次调用init
操作时执行的默认核心函数一起执行。 “我的自定义菜单”字符串是您将在管理页面中看到的可读版本。
在函数内部,核心函数 register_nav_menu 用于为我们的主题注册导航菜单位置。 如果要注册多个菜单,可以使用register_nav_menus()
并在数组中定义菜单位置,如下所示:
function my_custom_menu() { register_nav_menus( array( 'my-custom-menu' => _( 'My Custom Menu' ), 'my-custom-menu-2' =>_('My Second Custom Menu') ) ); } add_action( 'init', 'my_custom_menu' );
要确认结果,请转到外观 > 菜单下的管理区域。 您会注意到您的自定义菜单位置包含在菜单设置中。
注意:如果我们此时选择此位置,菜单将不会在前端显示任何内容。
如何显示我们的自定义菜单
假设我们希望将新菜单位置用于二级水平菜单,该二级菜单将位于我们主题中已经存在的“桌面水平菜单”下方。
为此,我们将在我们希望显示菜单的主题模板中插入一些代码。 在本例中,我们使用 Twenty Twenty 主题并编辑其 header.php 文件以显示我们的菜单。 您将在主题文件夹下找到此文件。
使用编辑器打开 header.php 文件,然后在第 33 行附近的代码中找到此元素。
<header class="header-footer-group" role="banner">
在本节下方,我们将放置代码以显示新的自定义菜单位置:“my-custom-menu”。
<header class="header-footer-group" role="banner"> <?php wp_nav_menu( array( 'theme_location' => 'my-custom-menu' ) ); ?>
theme_location 值必须与您在我们之前粘贴的 functions.php 代码中为菜单提供的名称相同。 在我们的例子中:“我的自定义菜单”。
现在让我们创建一个测试菜单来看看这是否有效。 为此,请转到外观 > 菜单并开始创建新菜单。
将菜单命名为“二级菜单”,为某个位置选择“我的自定义菜单”,然后点击“创建菜单”按钮。
最后将一些项目添加到菜单中(例如菜单项 1、菜单项 2、菜单项 3),然后保存菜单。
让我们看看我们现在在前端有什么。
我们已经设法展示了我们的新菜单,但它很乱,不是吗?
如果我们查看源代码,我们会注意到 wp_nav_menu() 函数创建了这段 HTML 代码
<div class="menu-secondary-menu-container"> <ul class="menu"> <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-378"><a href="#">Menu item 1</a></li> <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-381"><a href="#">Menu item 2</a></li> <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-382"><a href="#">Menu item 3</a></li> </ul> </div>
所以,我们可以使用代码中描述的类来美化我们的菜单。 为此,我们将使用一些 CSS。 找到 style.css(这通常与 header.php 文件位于同一位置),然后使用编辑器打开它以添加以下代码:
ul#menu-secondary-menu { text-align: right; padding: 10px 30px; } ul#menu-secondary-menu li { list-style: none; display: inline-block; padding: 1px; } ul#menu-secondary-menu li:hover { border: 1px solid #c00202; padding: 0; border-radius: 3px; } ul#menu-secondary-menu li a { text-decoration: none; padding: 5px; font-size: 14px; }
现在的结果会更整洁,更符合我们演示网站的风格。
额外的菜单定制
WordPress 提供的用于显示菜单的 wp_nav_menu() 函数带有一系列选项,可让您进一步自定义它。
'主题位置'
如上所述,该参数对应于functions.php中传递给register_nav_menus()函数的键
wp_nav_menu( array( 'theme_location' => 'my-custom-menu' ) );
'菜单类'
有一个“ menu_class ”选项,允许您为菜单指定自己的类。
wp_nav_menu( array( 'theme_location' => 'my-custom-menu', 'menu_class' => 'my-custom-menu' ) );
您可能已经注意到,该类不会替换任何其他类,而是添加到 ul 元素中。
'menu_id'
与 class 选项不同,menu_id 选项替换了当前菜单 id。 <ul> 元素生成的 HTML 将是这样的。
<ul class="menu">
不使用此选项时,id 将是 menu slug,在使用多个实例时将递增。
'容器'
此参数定义菜单周围元素的类型。 默认值为“div”。 例如,如果您使用此代码:
wp_nav_menu( array( 'theme_location' => 'my-custom-menu', 'container' => 'nav', ) );
你会得到这个结果:
'container_class'
这是一个应用于菜单父元素的类:
wp_nav_menu( array( 'theme_location' => 'my-custom-menu', 'container_class' => 'my-custom-menu-wrapper', ) );
您还可以使用 'before' 和 'after' 参数在每个菜单项链接之前或之后插入内容。 如果您想在前面添加破折号或图标或将菜单项包装在 span 标记中,这将非常有用。 您可以自己尝试下面的示例以查看实际情况:
wp_nav_menu( array( 'theme_location' => 'my-custom-menu', 'before' => '<span class="menulink">', 'after' => '</span>', ) );
wp_nav_menu( array( 'theme_location' => 'my-custom-menu', 'before' => '-', ) );
wp_nav_menu( array( 'theme_location' => 'my-custom-menu', 'before' => '-', ) );
您还可以将图标添加到菜单项。 例如,尝试安装 Font Awesome 插件以包含他们的图标库,并使用“之前”菜单选项将字体真棒图标应用于菜单项。
wp_nav_menu( array( 'theme_location' => 'my-custom-menu', 'before' => '<i class="fas fa-caret-right"></i>', ) );
您可以在插件的图标列表中找到每个图标的代码。
沃克参数
最后但同样重要的是,我们将提供一个示例,说明 walker 参数如何帮助自定义菜单。 如果您不知道 WordPress walker 类是什么,那么以下内容可能没有多大意义。 我们建议先阅读“熟悉 WordPress Walker 课程”。
wp_nav_menu( array( 'walker' => new Walker_Custom_Menu ) );
为了演示 Walker 类,我们将在菜单上添加一个“子项”。
我们将覆盖 WordPress 提供的默认 Walker 类。 它位于 wp-includes/class-walker-nav-menu.php 文件中。 为此,请转到您的 function.php 文件并插入以下代码:
if ( !class_exists('My_Nav_Menu_Walker') ) { class My_Nav_Menu_Walker extends Walker { var $tree_type = array( 'post_type', 'taxonomy', 'custom' ); var $db_fields = array( 'parent' => 'menu_item_parent', 'id' => 'db_id' ); function start_lvl(&$output, $depth) { $indent = str_repeat("\t", $depth); $output .= "\n$indent"; $output .= "<i class=\"dropdown icon\"></i>\n"; $output .= "<div class=\"menu\">\n"; } function end_lvl(&$output, $depth) { $indent = str_repeat("\t", $depth); $output .= "$indent</div>\n"; } function start_el(&$output, $item, $depth, $args) { $value = ''; $classes = empty( $item->classes ) ? array() : (array) $item->classes; $classes = in_array( 'current-menu-item', $classes ) ? array( 'current-menu-item' ) : array(); $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) ); $class_names = strlen( trim( $class_names ) ) > 0 ? ' class="' . esc_attr( $class_names ) . '"' : ''; $id = apply_filters( 'nav_menu_item_id', '', $item, $args ); $id = strlen( $id ) ? '' : ''; $attributes = ! empty( $item->attr_title ) ? ' title="' . esc_attr( $item->attr_title ) .'"' : ''; $attributes .= ! empty( $item->target ) ? ' target="' . esc_attr( $item->target ) .'"' : ''; $attributes .= ! empty( $item->xfn ) ? ' rel="' . esc_attr( $item->xfn ) .'"' : ''; $attributes .= ! empty( $item->url ) ? ' href="' . esc_attr( $item->url ) .'"' : ''; $item_output = $args->before; $item_output .= '<a'. $attributes . $id . $value . $class_names . '>'; $item_output .= '<div class="item">'; $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after; $item_output .= '</div>'; $item_output .= "</a>\n"; $item_output .= $args->after; $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args ); } } }
现在在你的 headers.php 中用这个替换你的菜单代码(我们将故意输出两个菜单版本只是为了比较结果):
wp_nav_menu(); // Default 'walker' => new Walker_Nav_Menu() wp_nav_menu( array( 'walker' => new My_Nav_Menu_Walker() ) );
将此代码与原始 Walker_Nav_Menu 类进行比较,您会注意到$tree_type
和$db_fields
保持不变,但其余部分已更改。 花点时间比较同一菜单的这两个版本上的代码和 HTML 输出,并尝试通过使用 My_Nav_Menu_Walker 类来试验自己。
结论
网站上的菜单显然非常重要! 能够完全控制菜单的放置和输出扩展了您作为主题开发人员的能力,并在设计网站时开辟了一系列令人兴奋的新可能性,而不必依赖插件,这总是很棒的。