这是一个老生常谈的问题,但今天可能仍然非常相关,所以我想我会piece of code 多年来,我不断发展。基本上,您可以在WordPress中定制菜单每个元素上的类,而无需开发自定义导航行者。这与实用程序优先的CSS框架工作(如Tailwind)越来越相关,它确实需要您访问标记或选项来添加自己的类。
它使用WordPress wp\\u nav\\u菜单功能和生命周期中可用的大多数过滤器在任何地方添加类。首先,像通常一样使用wp\\u nav\\u菜单,然后将自定义参数传递给函数。这些自定义参数然后由过滤器检测并在需要的地方添加类。
例如,可以通过仅向第一级列表元素添加类或仅向第三级链接添加背景图像/图标来创建自定义下拉菜单。所有可能的选项都在顶部的docblock中详细说明。
<?php
/**
 * WordPress filters to allow custom arguments to wp_nav_menu to,
 * in turn, allow custom classes to every element of a menu.
 *
 * You can apply a class only to certain depth of your menu as well.
 *
 * The filters use the depth argument given by WordPress
 * which is an index, thus starts with level 0 (zero).
 *
 * Custom Arguments supported : 
 * link_atts or link_atts_$depth            ->      Add any attribute to <a> elements
 * a_class or a_class_$depth                ->      Add classes to <a> elements
 * li_class or li_class_$depth              ->      Add classes to <li> elements
 * submenu_class or submenu_class_$depth    ->      Add classes to submenu <ul> elements
 *
 * Ex.: add a "text-black" class to all links and "text-blue" class only to 3rd level links
 * wp_nav_menu([
 *     \'theme_location\' => \'primary_navigation\',
 *     \'a_class\' => \'text-black\',
 *     \'a_class_2\'
 *     ...
 * ])
 *
 * Ex.: More complete example with some TailwindCSS classes and AlpineJS sugar
 * wp_nav_menu([
 *     \'theme_location\' => \'primary_navigation\',
 *     \'menu_class\' => \'relative w-full z-10 pl-0 list-none flex\',
 *     \'link_atts_0\' => [
 *         ":class" => "{ \'active\': tab === \'foo\' }",
 *         "@click" => "tab = \'foo\'"
 *     ],
 *     \'li_class\' => \'w-full\',
 *     \'li_class_0\' => \'mb-12\',
 *     \'a_class\' => \'text-sm xl:text-xl text-white border-b hover:border-white\',
 *     \'a_class_0\' => \'text-3xl xl:text-5xl relative dash-left js-stagger  a-mask after:bg-primary\',
 *     \'li_class_1\' => \'js-stagger a-mask after:bg-primary hidden lg:block\',
 *     \'a_class_1\' => \'flex h-full items-center uppercase py-2 relative border-white border-opacity-40 hover:border-opacity-100\',
 *     \'submenu_class\' => \'list-none pl-0 grid grid-cols-1 lg:grid-cols-2 lg:gap-x-12 xl:gap-x-24 xxl:gap-x-32\',
 *     \'container\'=>false
 * ])
 * 
 * @author davidwebca
 * @link https://gist.github.com/davidwebca/a7b278bbb0c0ce1d1ec5620126e863bb
 */
/**
 * Add custom attributes or classes to links in wp_nav_menu
 */
add_filter( \'nav_menu_link_attributes\', function ( $atts, $item, $args, $depth ) {
    if (property_exists($args, \'link_atts\')) {
        $atts = array_merge($atts, $args->link_atts);
    }
    if (property_exists($args, "link_atts_$depth")) {
        $atts = array_merge($atts, $args->{"link_atts_$depth"});
    }
    if(empty($atts[\'class\'])) {
        $atts[\'class\'] = \'\';
    }
    $classes = explode(\' \', $atts[\'class\']);
    /**
     * Fix for tailwindcss classes that include ":" (colon)
     * Enter triple underscore hover___text-primary instaed of hover:text-primary
     *
     * Some filters provided so that you can customize your own replacements,
     * passed directly to preg_replace so supports array replacements as well.
     *
     * WordPress trac following the issue of escaping CSS classes:
     * @link https://core.trac.wordpress.org/ticket/33924
     */
    $patterns = apply_filters( \'nav_menu_css_class_unescape_patterns\', \'/___/\');
    $replacements = apply_filters( \'nav_menu_css_class_unescape_replacements\', \':\' );
    $classes = array_map(function($cssclass) use( $patterns, $replacements) {
        return preg_replace($patterns, $replacements, $cssclass);
    }, $classes);
    if (property_exists($args, \'a_class\')) {
        $arr_classes = explode(\' \', $args->a_class);
        $classes = array_merge($classes, $arr_classes);
    }
    if (property_exists($args, "a_class_$depth")) {
        $arr_classes = explode(\' \', $args->{"a_class_$depth"});
        $classes = array_merge($classes, $arr_classes);
    }
    $atts[\'class\'] = implode(\' \', $classes);
    return $atts;
}, 1, 4 );
/**
 * Add custom classes to lis in wp_nav_menu
 */
add_filter( \'nav_menu_css_class\', function ( $classes, $item, $args, $depth ) {
    if (property_exists($args, \'li_class\')) {
        $arr_classes = explode(\' \', $args->li_class);
        $classes = array_merge($classes, $arr_classes);
    }
    if (property_exists($args, "li_class_$depth")) {
        $arr_classes = explode(\' \', $args->{"li_class_$depth"});
        $classes = array_merge($classes, $arr_classes);
    }
    return $classes;
}, 1, 4 );
/**
 * Add custom classes to ul.sub-menu in wp_nav_menu
 */
add_filter(\'nav_menu_submenu_css_class\', function( $classes, $args, $depth ) {
    if (property_exists($args, \'submenu_class\')) {
        $arr_classes = explode(\' \', $args->submenu_class);
        $classes = array_merge($classes, $arr_classes);
    }
    if (property_exists($args, "submenu_class_$depth")) {
        $arr_classes = explode(\' \', $args->{"submenu_class_$depth"});
        $classes = array_merge($classes, $arr_classes);
    }
    return $classes;
}, 1, 3);