Voici une sortie simple de la balise de menu de navigation par défaut:
<ul>
<li><a>First Item</a>
<ul class="sub-menu">
<li><a>Some Child Item</a></li>
<li><a>Some Child Item</a></li>
</ul>
</li>
<li><a>Second Item</a></li>
<li><a>Third Item</a></li>
</ul>
J'essaie d'ajouter le titre de l'élément parent à la section sub-menu
. Donc, j'essaie d'atteindre cet objectif:
<ul>
<li><a>First Item</a>
<ul class="sub-menu">
<h3>First Item</h3> <!-- I'm looking for this -->
<li><a>Some Child Item</a></li>
<li><a>Some Child Item</a></li>
</ul>
</li>
<li><a>Second Item</a></li>
<li><a>Third Item</a></li>
</ul>
J'ai creusé dans la classe Walker_Nav_Menu
et ses méthodes. La méthode responsable de la sortie du <ul>
est la méthode start_lvl
et je ne trouve pas le moyen de saisir l'objet ou l'ID de l'élément parent pour en récupérer le titre. Voici le contenu de cette fonction:
public function start_lvl( &$output, $depth = 0, $args = array() ) {
if ( isset( $args->item_spacing ) && 'discard' === $args->item_spacing ) {
$t = '';
$n = '';
} else {
$t = "\t";
$n = "\n";
}
$indent = str_repeat( $t, $depth );
// Default class.
$classes = array( 'sub-menu' );
/**
* Filters the CSS class(es) applied to a menu list element.
*
* @since 4.8.0
*
* @param array $classes The CSS classes that are applied to the menu `<ul>` element.
* @param stdClass $args An object of `wp_nav_menu()` arguments.
* @param int $depth Depth of menu item. Used for padding.
*/
$class_names = join( ' ', apply_filters( 'nav_menu_submenu_css_class', $classes, $args, $depth ) );
$class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';
$output .= "{$n}{$indent}<ul$class_names>{$n}";
}
Est-il possible de faire cela?
Je crois que wp_nav_menu()
gère la mise en forme de la liste de niveau supérieur afin que la méthode start_lvl
ne traite que les éléments de sous-menu (à ma connaissance). Cela ne nous donne pas non plus accès au $item
dont nous avons besoin pour obtenir le parent.
Ci-dessous, j'ai configuré une variable booléenne pour déterminer si nous devrions afficher notre titre ou non. Il conserve également sa validité HTML, les listes ne pouvant contenir que des éléments de liste. Il est donc préférable de styliser les éléments de liste avec une classe spécifique. Le code ci-dessous provient à 90% de Core WP_Nav_Menu Walker
Nous devons d’abord configurer notre variable:
class Title_Sub_Menus extends Walker_Nav_Menu {
/**
* Track Whether to show parent title
*
* @var Boolean
*/
private $show_parent_title = false;
/* ... */
}
Ensuite, nous devons activer notre variable switch chaque fois qu'un nouveau sous-menu est créé:
class Title_Sub_Menus extends Walker_Nav_Menu {
/* ... */
/**
* Starts the list before the elements are added.
*
* @since 3.0.0
*
* @see Walker::start_lvl()
*
* @param string $output Used to append additional content (passed by reference).
* @param int $depth Depth of menu item. Used for padding.
* @param stdClass $args An object of wp_nav_menu() arguments.
*/
public function start_lvl( &$output, $depth = 0, $args = array() ) {
if ( isset( $args->item_spacing ) && 'discard' === $args->item_spacing ) {
$t = '';
$n = '';
} else {
$t = "\t";
$n = "\n";
}
$indent = str_repeat( $t, $depth );
// Default class.
$classes = array( 'sub-menu' );
// Enable Submenu Title
$this->show_parent_title = true;
/**
* Filters the CSS class(es) applied to a menu list element.
*
* @since 4.8.0
*
* @param array $classes The CSS classes that are applied to the menu `<ul>` element.
* @param stdClass $args An object of `wp_nav_menu()` arguments.
* @param int $depth Depth of menu item. Used for padding.
*/
$class_names = join( ' ', apply_filters( 'nav_menu_submenu_css_class', $classes, $args, $depth ) );
$class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';
$output .= "{$n}{$indent}<ul$class_names>{$n}";
}
/* ... */
} // END class Title_Sub_Menus
C'est là que les choses se compliquent un peu. Autant que je sache, les titres d'objet d'élément de menu ne sont pas enregistrés avec l'élément s'il n'a pas changé par rapport au titre d'origine. Si le titre de la page d'origine est "Page WordPress" et que vous modifiez le titre de l'élément de menu en "WordPress" après l'avoir ajouté au menu, il est alors enregistré dans l'élément de menu. Nous devrions également vérifier contre des termes. Bravo à la réponse d'Alex Sancho.
Class Title_Sub_Menus extends Walker_Nav_Menu {
/* ... */
/**
* Starts the element output.
*
* @since 3.0.0
* @since 4.4.0 The {@see 'nav_menu_item_args'} filter was added.
*
* @see Walker::start_el()
*
* @param string $output Used to append additional content (passed by reference).
* @param WP_Post $item Menu item data object.
* @param int $depth Depth of menu item. Used for padding.
* @param stdClass $args An object of wp_nav_menu() arguments.
* @param int $id Current item ID.
*/
public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
// Maybe show parent title
if( 0 === $depth && $this->show_parent_title ) {
// Grab the title if the user HAS changed it from the original
$title = get_the_title( $item->menu_item_parent );
if( empty( $title ) ) {
// Title is the original title, grab it from the original post or term.
$object_id = get_post_meta( $item->menu_item_parent, '_menu_item_object_id', true );
$object = get_post_meta( $item->menu_item_parent, '_menu_item_object', true );
$type = get_post_meta( $item->menu_item_parent, '_menu_item_type', true );
if ( 'post_type' === $type ) {
$title = get_post( $object_id )->post_title;
} elseif ( 'taxonomy' === $type) {
$title = get_term( $object_id, $object )->name;
}
}
$output .= sprintf( '<li class="parentTitle"><h3>%1$s</h3></li>', $title ); // Display our title
// Parent title displayed, turn off switch
$this->show_parent_title = false;
}
/* ... */
}
} // END class Title_Sub_Menus
class Title_Sub_Menus extends Walker_Nav_Menu {
/**
* Track Whether to show parent title
*
* @var Boolean
*/
private $show_parent_title = false;
/**
* Starts the list before the elements are added.
*
* @since 3.0.0
*
* @see Walker::start_lvl()
*
* @param string $output Used to append additional content (passed by reference).
* @param int $depth Depth of menu item. Used for padding.
* @param stdClass $args An object of wp_nav_menu() arguments.
*/
public function start_lvl( &$output, $depth = 0, $args = array() ) {
if ( isset( $args->item_spacing ) && 'discard' === $args->item_spacing ) {
$t = '';
$n = '';
} else {
$t = "\t";
$n = "\n";
}
$indent = str_repeat( $t, $depth );
// Default class.
$classes = array( 'sub-menu' );
$this->show_parent_title = true;
/**
* Filters the CSS class(es) applied to a menu list element.
*
* @since 4.8.0
*
* @param array $classes The CSS classes that are applied to the menu `<ul>` element.
* @param stdClass $args An object of `wp_nav_menu()` arguments.
* @param int $depth Depth of menu item. Used for padding.
*/
$class_names = join( ' ', apply_filters( 'nav_menu_submenu_css_class', $classes, $args, $depth ) );
$class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';
$output .= "{$n}{$indent}<ul$class_names>{$n}";
}
/**
* Starts the element output.
*
* @since 3.0.0
* @since 4.4.0 The {@see 'nav_menu_item_args'} filter was added.
*
* @see Walker::start_el()
*
* @param string $output Used to append additional content (passed by reference).
* @param WP_Post $item Menu item data object.
* @param int $depth Depth of menu item. Used for padding.
* @param stdClass $args An object of wp_nav_menu() arguments.
* @param int $id Current item ID.
*/
public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
// Maybe show parent title
if( 0 === $depth && $this->show_parent_title ) {
$object_id = get_post_meta( $item->menu_item_parent, '_menu_item_object_id', true );
$object = get_post_meta( $item->menu_item_parent, '_menu_item_object', true );
$type = get_post_meta( $item->menu_item_parent, '_menu_item_type', true );
$title = get_the_title( $item->menu_item_parent );
if( empty( $title ) ) {
if ( 'post_type' == $type ) {
$title = get_post( $object_id )->post_title;
} elseif ( 'taxonomy' == $type) {
$title = get_term( $object_id, $object )->name;
}
}
$output .= sprintf( '<li class="parentTitle"><h3>%1$s</h3></li>', $title ); // OR post_parent if dynamically generated
$this->show_parent_title = false;
}
if ( isset( $args->item_spacing ) && 'discard' === $args->item_spacing ) {
$t = '';
$n = '';
} else {
$t = "\t";
$n = "\n";
}
$indent = ( $depth ) ? str_repeat( $t, $depth ) : '';
$classes = empty( $item->classes ) ? array() : (array) $item->classes;
$classes[] = 'menu-item-' . $item->ID;
/**
* Filters the arguments for a single nav menu item.
*
* @since 4.4.0
*
* @param stdClass $args An object of wp_nav_menu() arguments.
* @param WP_Post $item Menu item data object.
* @param int $depth Depth of menu item. Used for padding.
*/
$args = apply_filters( 'nav_menu_item_args', $args, $item, $depth );
/**
* Filters the CSS class(es) applied to a menu item's list item element.
*
* @since 3.0.0
* @since 4.1.0 The `$depth` parameter was added.
*
* @param array $classes The CSS classes that are applied to the menu item's `<li>` element.
* @param WP_Post $item The current menu item.
* @param stdClass $args An object of wp_nav_menu() arguments.
* @param int $depth Depth of menu item. Used for padding.
*/
$class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args, $depth ) );
$class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';
/**
* Filters the ID applied to a menu item's list item element.
*
* @since 3.0.1
* @since 4.1.0 The `$depth` parameter was added.
*
* @param string $menu_id The ID that is applied to the menu item's `<li>` element.
* @param WP_Post $item The current menu item.
* @param stdClass $args An object of wp_nav_menu() arguments.
* @param int $depth Depth of menu item. Used for padding.
*/
$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 : '';
/**
* Filters the HTML attributes applied to a menu item's anchor element.
*
* @since 3.6.0
* @since 4.1.0 The `$depth` parameter was added.
*
* @param array $atts {
* The HTML attributes applied to the menu item's `<a>` element, empty strings are ignored.
*
* @type string $title Title attribute.
* @type string $target Target attribute.
* @type string $rel The rel attribute.
* @type string $href The href attribute.
* }
* @param WP_Post $item The current menu item.
* @param stdClass $args An object of wp_nav_menu() arguments.
* @param int $depth Depth of menu item. Used for padding.
*/
$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 . '"';
}
}
/** This filter is documented in wp-includes/post-template.php */
$title = apply_filters( 'the_title', $item->title, $item->ID );
/**
* Filters a menu item's title.
*
* @since 4.4.0
*
* @param string $title The menu item's title.
* @param WP_Post $item The current menu item.
* @param stdClass $args An object of wp_nav_menu() arguments.
* @param int $depth Depth of menu item. Used for padding.
*/
$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;
/**
* Filters a menu item's starting output.
*
* The menu item's starting output only includes `$args->before`, the opening `<a>`,
* the menu item's title, the closing `</a>`, and `$args->after`. Currently, there is
* no filter for modifying the opening and closing `<li>` for a menu item.
*
* @since 3.0.0
*
* @param string $item_output The menu item's starting HTML output.
* @param WP_Post $item Menu item data object.
* @param int $depth Depth of menu item. Used for padding.
* @param stdClass $args An object of wp_nav_menu() arguments.
*/
$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
}
} // END class Title_Sub_Menus
Cela me semble un peu brouillon/étrange, il n’ya pas de moyen plus simple ni plus simple de procéder, c’est donc une solution possible. Espérons que quelqu'un propose une solution et une explication plus intuitive.