class-walker-nav-menu.php 8.5 KB

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