web-dev-qa-db-fra.com

Nombre d'éléments dans un menu

Je ne trouve pas si WordPress enregistre le nombre d'éléments dans un menu. En gros, j'ai besoin de savoir combien d'éléments sont dans un menu pour calculer le pourcentage que chaque élément devrait prendre dans la barre d'en-tête. Y a-t-il une fonction? Ou est le meilleur moyen d'y parvenir en faisant quelque chose avec WP_Query?

2
Chess Byte

J'étais curieux et j'ai décidé de vérifier, peu importe si c'était pertinent pour un problème de CSS ;-)

J'ai d'abord jeté un coup d'œil dans les tables de la base de données pour en savoir plus sur la structure du menu:

Menu - blocs de construction

Chaque menu de navigation est enregistré en tant que terme dans la taxonomie nav_menu.

Ensuite, lorsque nous ajoutons des éléments à ce menu, nous créons de nouveaux objets de publication du type nav_menu_item.

Maintenant, la partie la plus délicate, où est l’arborescence de ce menu?

Ce n'est pas celui qui est stocké dans le champ post_parent des articles nav_menu_item, comme prévu.

Nous le trouvons en fait dans la table de méta de publication où il est stocké sous la clé de méta _menu_item_menu_item_parent, pour chaque publication de nav_menu_item.

Maintenant, il y a différentes façons d'obtenir le décompte. Voici quelques exemples:

Exemple - get_term_by()/wp_get_nav_menu_object()

Commençons par la plus simple: si nous avons besoin d’obtenir le nombre d’éléments dans un menu particulier, nous pouvons l’obtenir à partir d’une requête de terme, car il est stocké dans la colonne count de la table wp_term_taxonomy.

Nous obtenons d’abord le terme de menu avec:

$menuterm = get_term_by( 'slug', 'some-menu-slug', 'nav_menu' );

Il existe un wrapper pour cela, à savoir:

$menuterm = wp_get_nav_menu_object( 'some-menu-slug' );

Pour obtenir le nombre total d'éléments dans le menu, nous pouvons ensuite utiliser:

$total_count = ( $menuterm instanceof \WP_Term ) ? $menuterm->count : 0;

Exemple - WP_Query()/get_posts()

Si nous voulons uniquement compter les éléments de menu sans parents, nous pouvons collecter tous les objets de publication dans notre menu avec:

if( $menuterm instanceof \WP_Term )
   $pids = get_objects_in_term( $menuterm->term_id, 'nav_menu' );

$pids est un tableau d'ID de publication.

Ensuite, nous pouvons faire la méta requête suivante:

$args = [
    'post__in'            => $pids,
    'post_type'           => 'nav_menu_item',
    'fields'              => 'ids',
    'ignore_sticky_posts' => true,
    'nopaging'            => true,
    'meta_query'          => [
        [
            'key'       => '_menu_item_menu_item_parent',
            'value'     => 0,
            'compare'   => '=',
        ]
    ]
]; 

$count = count( get_posts( $args ) );

Il y a aussi un moyen avec:

$q = new WP_Query();
$count = count( $q->query( $args ) );

ou juste:

$count = $q->found_posts;

avec l’astuce habituelle, posts_per_page en tant que 1, pour réduire les données extraites.

Exemple - wp_get_nav_menu_items()

Il existe des wrappers pratiques dans le noyau, tels que wp_get_nav_menu_items( $menu, $args )$args sont des arguments get_posts().

Voici un moyen:

$count = count( 
    wp_list_filter( 
        wp_get_nav_menu_items( 'some-menu-slug' ), 
       [ 'menu_item_parent' => 0 ] 
    ) 
);

Nous pouvons également utiliser:

$args = [
    'meta_query'    => [
        [
            'key'       => '_menu_item_menu_item_parent',
            'value'     => 0,
            'compare'   => '=',
        ]
    ]
];

$count = count( wp_get_nav_menu_items( 'some-menu-slug', $args ) );

Exemple - filtre/crochets

Il existe de nombreux filtres/actions auxquels nous pourrions adhérer pour effectuer le comptage, par exemple: le filtre wp_get_nav_menu_items. Même des crochets dans le navigateur de menu de navigation.

Nous pourrions même nous connecter au wp_update_nav_menu qui se déclenche lorsque le menu est mis à jour. Ensuite, nous pourrions compter les articles sans parents et les stocker, par exemple. comme méta-données de terme.

Ensuite, il y a aussi différentes manières avec javascript.

J'espère que cela vous donnera quelques idées pour aller plus loin.

5
birgire

Merci pour l'aide birgire. Cela m'a donné beaucoup à penser. Finalement, j'ai trouvé une solution utilisant un filtre. Je peux compter le nombre de parents du menu. Le seul problème avec cette approche est qu’elle sera exécutée chaque fois qu’un menu est affiché.

function my_nav_menu_objects($sorted_menu_items, $args) 
{
  if($args->menu == 'header_menu')
  {
    $counter = 0;

    foreach($sorted_menu_items as $sorted_menu_item)
    {
      if($sorted_menu_item->menu_item_parent == 0) 
      {
        $counter++;
      }
    }

    echo 'Menu Count: ' . $counter;
  }

  return $sorted_menu_items;
}
add_filter('wp_nav_menu_objects', 'my_nav_menu_objects', 10, 2);

Modifiez le "header_menu" en indiquant le type de slug de votre navigation que vous souhaitez vérifier. Vous pouvez ensuite stocker cela dans une option et l'appeler si nécessaire.

1
Chess Byte