Número de itens em um menu

Não consigo encontrar se o WordPress armazena o número de itens em um menu. Basicamente eu preciso descobrir quantos itens estão em um menu para calcular a porcentagem que cada item deve ocupar na barra de header. Existe uma function? Ou é a melhor maneira de conseguir isso fazendo algo com o WP_Query ?

Solutions Collecting From Web of "Número de itens em um menu"

Fiquei curioso e decidi verificar isso, independentemente de ser relevante para um problema CSS 😉

Primeiro, examinei as tabelas do database para encontrar mais sobre a estrutura do menu:

Menu – blocos de construção

Cada menu de navegação é registrado como um termo na taxonomia nav_menu .

Então, quando adicionamos itens a esse menu, estamos criando novos objects de postagem do tipo nav_menu_item .

Agora, a parte complicada, onde está armazenada a estrutura da tree desse menu?

Não é armazenado no campo post_parent nav_menu_item postagens nav_menu_item , como esperado.

Na verdade, encontrá-lo na meta-meta do post, onde é armazenado sob a meta-chave _menu_item_menu_item_parent , para cada publicação nav_menu_item .

Agora, existem várias maneiras de obter a contagem. Aqui estão alguns exemplos:

Exemplo – get_term_by() / wp_get_nav_menu_object()

Primeiro o fácil: se precisarmos obter o número de itens em um menu específico, podemos obtê-lo de uma consulta de termo, porque está armazenado na coluna de count da tabela wp_term_taxonomy .

Primeiro recebemos o termo do menu com:

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

Existe um invólucro para isso, a saber:

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

Para obter a contagem total de itens no menu, podemos usar:

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

Exemplo – WP_Query() / get_posts()

Se quisermos apenas contar itens de menu sem pais, podemos coletar todos os objects de postagem dentro do nosso menu com:

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

onde $pids é uma matriz de IDs de postagem.

Então podemos fazer a seguinte meta-consulta:

 $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 ) ); 

Há também uma maneira com:

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

ou apenas:

 $count = $q->found_posts; 

com o truque comum, posts_per_page como 1, para reduzir os dados obtidos.

Exemplo – wp_get_nav_menu_items()

Existem wrappers úteis no núcleo, como wp_get_nav_menu_items( $menu, $args ) onde $args são argumentos get_posts() .

Aqui está uma maneira:

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

Nós também podemos usar:

 $args = [ 'meta_query' => [ [ 'key' => '_menu_item_menu_item_parent', 'value' => 0, 'compare' => '=', ] ] ]; $count = count( wp_get_nav_menu_items( 'some-menu-slug', $args ) ); 

Exemplo – filtro / ganchos

Existem muitos filtros / ações que podemos conectar para fazer a contagem, por exemplo, o filtro wp_get_nav_menu_items . Mesmo ganchos dentro do navegador do menu NAV.

Poderíamos nos conectar ao wp_update_nav_menu que triggers quando o menu é atualizado. Então, podemos contar os itens sem pais e armazená-lo, por exemplo, como meta-dados do termo.

Depois, existem várias maneiras com javascript.

Espero que isso lhe dê algumas idéias para levar adiante.

Obrigado pela ajuda de birgire. Isso me deu muito para pensar. Eventualmente, eu encontrei uma solução usando um filtro. Posso contar o número de pais que o menu tem. O único problema com essa abordagem é que ele será executado sempre que um menu for exibido.

 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); 

Mude o “header_menu” para o que nunca o slug da sua navegação que deseja verificar é. Você poderia então armazenar isso em uma opção e chamá-lo quando necessário.