你可以利用wp的walker class来实现自定义二级甚至mage menu菜单。
class Custom_Nav_Walker extends Walker_Nav_Menu { public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) { $indent = ( $depth ) ? str_repeat( "\t", $depth ) : ''; $classes = empty( $item->classes ) ? array() : (array) $item->classes; $classes[] = 'menu-item-' . $item->ID; $args = apply_filters( 'nav_menu_item_args', $args, $item, $depth ); $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args, $depth ) ); $class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : ''; $id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args, $depth ); $id = $id ? ' id="' . esc_attr( $id ) . '"' : ''; $output .= $indent . '<li' . $id . $class_names .'>'; $atts = array(); $atts['title'] = ! empty( $item->attr_title ) ? $item->attr_title : ''; $atts['target'] = ! empty( $item->target ) ? $item->target : ''; $atts['rel'] = ! empty( $item->xfn ) ? $item->xfn : ''; $atts['href'] = ! empty( $item->url ) ? $item->url : ''; $atts = apply_filters( 'nav_menu_link_attributes', $atts, $item, $args, $depth ); $attributes = ''; foreach ( $atts as $attr => $value ) { if ( ! empty( $value ) ) { $value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value ); $attributes .= ' ' . $attr . '="' . $value . '"'; } } $title = apply_filters( 'the_title', $item->title, $item->ID ); $title = apply_filters( 'nav_menu_item_title', $title, $item, $args, $depth ); $item_output = $args->before; $item_output .= '<a'. $attributes .'>'; $item_output .= $args->link_before . $title . $args->link_after; $item_output .= '</a>'; $item_output .= $args->after; $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
各部分逐行讲解
class Custom_Nav_Walker extends Walker_Nav_Menu {
该行创建了一个名为 Custom_Nav_Walker 的新类,并扩展了内置的 Walker_Nav_Menu 类。 通过扩展内置类,我们可以使用它的功能和方法,还可以覆盖某些方法来自定义输出。
public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
为每个菜单项调用 start_el 方法,它负责为起始 li标记和链接a标记生成 HTML。 &$output 参数通过引用传递,这意味着在此方法中对其所做的任何更改都将反映在最终的 HTML 输出中。 传递给此方法的其他参数是:
$item:当前菜单项
$depth:层次结构中菜单项的当前深度
$args:传递给 wp_nav_menu 函数的参数
$id:菜单项的ID
$indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
此行基于当前菜单项的 $depth 创建缩进。 这用于正确缩进 HTML 输出,以便子项在其父项下方正确缩进。
$classes = empty( $item->classes ) ? array() : (array) $item->classes; $classes[] = 'menu-item-' . $item->ID;
此行获取分配给当前菜单项的样式class。 它确保 $item 对象的 classes 属性是一个数组,然后添加“menu-item-ID” class,其中“ID”是当前菜单项的唯一 ID。
$args = apply_filters( 'nav_menu_item_args', $args, $item, $depth );
此行对 $args 数组应用过滤器,允许代码的其他部分修改传递给 wp_nav_menu 函数的参数。
$class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args, $depth ) ); $class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';
此行过滤并连接菜单项的class,并将字符串 class=”class1 class2 class3″ 添加到菜单项的 li 元素。
$id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args, $depth ); $id = $id ? ' id="' . esc_attr( $id ) . '"' : '';
此行根据其 ID 为菜单项创建 ID 属性并对其应用过滤器,从而允许代码的其他部分修改 ID。
$output .= $indent . '<li' . $id . $class_names .'>';
此行将开始li标记添加到输出,以及之前创建的 ID 和类属性。 在开头添加缩进以保持菜单的正确层次结构。
$atts = array(); $atts['title'] = ! empty( $item->attr_title ) ? $item->attr_title : ''; $atts['target'] = ! empty( $item->target ) ? $item->target : ''; $atts['rel'] = ! empty( $item->xfn ) ? $item->xfn : ''; $atts['href'] = ! empty( $item->url ) ? $item->url : '';
此代码块为 a 标记创建一个属性数组,这些属性是从 $item 对象中提取的。 如果值不为空,则将其添加到数组中,否则将为空字符串
$atts = apply_filters( 'nav_menu_link_attributes', $atts, $item, $args, $depth );
此行对属性数组应用过滤器,允许代码的其他部分修改属性。
$attributes = ''; foreach ( $atts as $attr => $value ) { if ( ! empty( $value ) ) { $value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value ); $attributes .= ' ' . $attr . '="' . $value . '"'; } }
此代码块遍历属性数组,将每个属性添加到 $attributes 字符串。 如果该属性的值不为空,则将其连同其名称和 = 符号添加到字符串中。 此外,如果属性为“href”,它将对 URL 进行转义
$title = apply_filters( 'the_title', $item->title, $item->ID ); $title = apply_filters( 'nav_menu_item_title', $title, $item, $args, $depth );
此行将两个过滤器应用于菜单项的标题:the_title 和 nav_menu_item_title。 这些过滤器允许代码的其他部分修改标题。
$item_output = $args->before; $item_output .= '<a'. $attributes .'>'; $item_output .= $args->link_before . $title . $args->link_after; $item_output .= '</a>'; $item_output .= $args->after;
此代码块创建 $item_output 变量,其中包含菜单项的完整 HTML 输出。 $args->before 和 $args->after 变量分别添加在输出的开头和结尾。
$args->link_before 和 $args->link_after 将添加在菜单标题前后。
$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
该行将最终的 $item_output HTML 添加到 $output 变量,并对其应用过滤器,允许代码的其他部分对其进行修改。
}
这个右花括号表示 start_el 方法的结束。
public function end_el( &$output, $item, $depth = 0, $args = array() ) { $output .= "</li>\n"; }
每个菜单项都会调用 end_el 方法,它负责为结束 标记生成 HTML。 &$output 参数通过引用传递,这意味着在此方法中对其所做的任何更改都将反映在最终的 HTML 输出中。
}
这个右大括号表示 Custom_Nav_Walker 类的结束。
这个自定义 walker 类负责菜单的基本结构,能够添加自定义类、属性或更改 HTML 结构。 但您可以将其用作基础并在此基础上进行构建,具体取决于您的特定需求。