class-walker-nav-menu.php (8645B)
1 <?php 2 /** 3 * Nav Menu API: Walker_Nav_Menu class 4 * 5 * @package WordPress 6 * @subpackage Nav_Menus 7 * @since 4.6.0 8 */ 9 10 /** 11 * Core class used to implement an HTML list of nav menu items. 12 * 13 * @since 3.0.0 14 * 15 * @see Walker 16 */ 17 class Walker_Nav_Menu extends Walker { 18 /** 19 * What the class handles. 20 * 21 * @since 3.0.0 22 * @var string 23 * 24 * @see Walker::$tree_type 25 */ 26 public $tree_type = array( 'post_type', 'taxonomy', 'custom' ); 27 28 /** 29 * Database fields to use. 30 * 31 * @since 3.0.0 32 * @todo Decouple this. 33 * @var array 34 * 35 * @see Walker::$db_fields 36 */ 37 public $db_fields = array( 38 'parent' => 'menu_item_parent', 39 'id' => 'db_id', 40 ); 41 42 /** 43 * Starts the list before the elements are added. 44 * 45 * @since 3.0.0 46 * 47 * @see Walker::start_lvl() 48 * 49 * @param string $output Used to append additional content (passed by reference). 50 * @param int $depth Depth of menu item. Used for padding. 51 * @param stdClass $args An object of wp_nav_menu() arguments. 52 */ 53 public function start_lvl( &$output, $depth = 0, $args = null ) { 54 if ( isset( $args->item_spacing ) && 'discard' === $args->item_spacing ) { 55 $t = ''; 56 $n = ''; 57 } else { 58 $t = "\t"; 59 $n = "\n"; 60 } 61 $indent = str_repeat( $t, $depth ); 62 63 // Default class. 64 $classes = array( 'sub-menu' ); 65 66 /** 67 * Filters the CSS class(es) applied to a menu list element. 68 * 69 * @since 4.8.0 70 * 71 * @param string[] $classes Array of the CSS classes that are applied to the menu `<ul>` element. 72 * @param stdClass $args An object of `wp_nav_menu()` arguments. 73 * @param int $depth Depth of menu item. Used for padding. 74 */ 75 $class_names = implode( ' ', apply_filters( 'nav_menu_submenu_css_class', $classes, $args, $depth ) ); 76 $class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : ''; 77 78 $output .= "{$n}{$indent}<ul$class_names>{$n}"; 79 } 80 81 /** 82 * Ends the list of after the elements are added. 83 * 84 * @since 3.0.0 85 * 86 * @see Walker::end_lvl() 87 * 88 * @param string $output Used to append additional content (passed by reference). 89 * @param int $depth Depth of menu item. Used for padding. 90 * @param stdClass $args An object of wp_nav_menu() arguments. 91 */ 92 public function end_lvl( &$output, $depth = 0, $args = null ) { 93 if ( isset( $args->item_spacing ) && 'discard' === $args->item_spacing ) { 94 $t = ''; 95 $n = ''; 96 } else { 97 $t = "\t"; 98 $n = "\n"; 99 } 100 $indent = str_repeat( $t, $depth ); 101 $output .= "$indent</ul>{$n}"; 102 } 103 104 /** 105 * Starts the element output. 106 * 107 * @since 3.0.0 108 * @since 4.4.0 The {@see 'nav_menu_item_args'} filter was added. 109 * 110 * @see Walker::start_el() 111 * 112 * @param string $output Used to append additional content (passed by reference). 113 * @param WP_Post $item Menu item data object. 114 * @param int $depth Depth of menu item. Used for padding. 115 * @param stdClass $args An object of wp_nav_menu() arguments. 116 * @param int $id Current item ID. 117 */ 118 public function start_el( &$output, $item, $depth = 0, $args = null, $id = 0 ) { 119 if ( isset( $args->item_spacing ) && 'discard' === $args->item_spacing ) { 120 $t = ''; 121 $n = ''; 122 } else { 123 $t = "\t"; 124 $n = "\n"; 125 } 126 $indent = ( $depth ) ? str_repeat( $t, $depth ) : ''; 127 128 $classes = empty( $item->classes ) ? array() : (array) $item->classes; 129 $classes[] = 'menu-item-' . $item->ID; 130 131 /** 132 * Filters the arguments for a single nav menu item. 133 * 134 * @since 4.4.0 135 * 136 * @param stdClass $args An object of wp_nav_menu() arguments. 137 * @param WP_Post $item Menu item data object. 138 * @param int $depth Depth of menu item. Used for padding. 139 */ 140 $args = apply_filters( 'nav_menu_item_args', $args, $item, $depth ); 141 142 /** 143 * Filters the CSS classes applied to a menu item's list item element. 144 * 145 * @since 3.0.0 146 * @since 4.1.0 The `$depth` parameter was added. 147 * 148 * @param string[] $classes Array of the CSS classes that are applied to the menu item's `<li>` element. 149 * @param WP_Post $item The current menu item. 150 * @param stdClass $args An object of wp_nav_menu() arguments. 151 * @param int $depth Depth of menu item. Used for padding. 152 */ 153 $class_names = implode( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args, $depth ) ); 154 $class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : ''; 155 156 /** 157 * Filters the ID applied to a menu item's list item element. 158 * 159 * @since 3.0.1 160 * @since 4.1.0 The `$depth` parameter was added. 161 * 162 * @param string $menu_id The ID that is applied to the menu item's `<li>` element. 163 * @param WP_Post $item The current menu item. 164 * @param stdClass $args An object of wp_nav_menu() arguments. 165 * @param int $depth Depth of menu item. Used for padding. 166 */ 167 $id = apply_filters( 'nav_menu_item_id', 'menu-item-' . $item->ID, $item, $args, $depth ); 168 $id = $id ? ' id="' . esc_attr( $id ) . '"' : ''; 169 170 $output .= $indent . '<li' . $id . $class_names . '>'; 171 172 $atts = array(); 173 $atts['title'] = ! empty( $item->attr_title ) ? $item->attr_title : ''; 174 $atts['target'] = ! empty( $item->target ) ? $item->target : ''; 175 if ( '_blank' === $item->target && empty( $item->xfn ) ) { 176 $atts['rel'] = 'noopener'; 177 } else { 178 $atts['rel'] = $item->xfn; 179 } 180 $atts['href'] = ! empty( $item->url ) ? $item->url : ''; 181 $atts['aria-current'] = $item->current ? 'page' : ''; 182 183 /** 184 * Filters the HTML attributes applied to a menu item's anchor element. 185 * 186 * @since 3.6.0 187 * @since 4.1.0 The `$depth` parameter was added. 188 * 189 * @param array $atts { 190 * The HTML attributes applied to the menu item's `<a>` element, empty strings are ignored. 191 * 192 * @type string $title Title attribute. 193 * @type string $target Target attribute. 194 * @type string $rel The rel attribute. 195 * @type string $href The href attribute. 196 * @type string $aria-current The aria-current attribute. 197 * } 198 * @param WP_Post $item The current menu item. 199 * @param stdClass $args An object of wp_nav_menu() arguments. 200 * @param int $depth Depth of menu item. Used for padding. 201 */ 202 $atts = apply_filters( 'nav_menu_link_attributes', $atts, $item, $args, $depth ); 203 204 $attributes = ''; 205 foreach ( $atts as $attr => $value ) { 206 if ( is_scalar( $value ) && '' !== $value && false !== $value ) { 207 $value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value ); 208 $attributes .= ' ' . $attr . '="' . $value . '"'; 209 } 210 } 211 212 /** This filter is documented in wp-includes/post-template.php */ 213 $title = apply_filters( 'the_title', $item->title, $item->ID ); 214 215 /** 216 * Filters a menu item's title. 217 * 218 * @since 4.4.0 219 * 220 * @param string $title The menu item's title. 221 * @param WP_Post $item The current menu item. 222 * @param stdClass $args An object of wp_nav_menu() arguments. 223 * @param int $depth Depth of menu item. Used for padding. 224 */ 225 $title = apply_filters( 'nav_menu_item_title', $title, $item, $args, $depth ); 226 227 $item_output = $args->before; 228 $item_output .= '<a' . $attributes . '>'; 229 $item_output .= $args->link_before . $title . $args->link_after; 230 $item_output .= '</a>'; 231 $item_output .= $args->after; 232 233 /** 234 * Filters a menu item's starting output. 235 * 236 * The menu item's starting output only includes `$args->before`, the opening `<a>`, 237 * the menu item's title, the closing `</a>`, and `$args->after`. Currently, there is 238 * no filter for modifying the opening and closing `<li>` for a menu item. 239 * 240 * @since 3.0.0 241 * 242 * @param string $item_output The menu item's starting HTML output. 243 * @param WP_Post $item Menu item data object. 244 * @param int $depth Depth of menu item. Used for padding. 245 * @param stdClass $args An object of wp_nav_menu() arguments. 246 */ 247 $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args ); 248 } 249 250 /** 251 * Ends the element output, if needed. 252 * 253 * @since 3.0.0 254 * 255 * @see Walker::end_el() 256 * 257 * @param string $output Used to append additional content (passed by reference). 258 * @param WP_Post $item Page data object. Not used. 259 * @param int $depth Depth of page. Not Used. 260 * @param stdClass $args An object of wp_nav_menu() arguments. 261 */ 262 public function end_el( &$output, $item, $depth = 0, $args = null ) { 263 if ( isset( $args->item_spacing ) && 'discard' === $args->item_spacing ) { 264 $t = ''; 265 $n = ''; 266 } else { 267 $t = "\t"; 268 $n = "\n"; 269 } 270 $output .= "</li>{$n}"; 271 } 272 273 }