Número de elementos en un menú

2

No puedo encontrar si WordPress almacena la cantidad de elementos en un menú. Básicamente, necesito averiguar cuántos elementos hay en un menú para calcular el porcentaje que cada elemento debe ocupar en la barra de encabezado. ¿Hay una función? ¿O es la mejor manera de lograr esto haciendo algo con WP_Query ?

    
pregunta Chess Byte 02.07.2016 - 23:12

2 respuestas

5

Tenía curiosidad y decidí comprobarlo, independientemente de si es relevante para un problema de CSS ;-)

Primero eché un vistazo a las tablas de la base de datos para encontrar más información sobre la estructura del menú:

Menú - bloques de construcción

Cada menú de navegación se registra como un término en la taxonomía nav_menu .

Luego, cuando agregamos elementos a ese menú, estamos creando nuevos objetos de publicación del tipo nav_menu_item .

Ahora, la parte difícil, ¿dónde está almacenada la estructura de árbol para ese menú?

No es el almacenado en el campo post_parent de las publicaciones nav_menu_item , como se esperaba.

En realidad, lo encontramos en la tabla de metadatos de la publicación, donde se almacena en la clave de meta _menu_item_menu_item_parent , para cada publicación nav_menu_item .

Ahora hay varias maneras de obtener el recuento. Aquí hay algunos ejemplos:

Ejemplo - get_term_by() / wp_get_nav_menu_object()

Primero el sencillo: si necesitamos obtener el número de elementos en un menú en particular, podemos obtenerlo de una consulta de términos, porque se almacena en la columna count de la tabla wp_term_taxonomy .

Primero obtenemos el término del menú con:

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

Existe una envoltura para esto, a saber:

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

Para obtener el recuento total de elementos en el menú, podemos usar:

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

Ejemplo - WP_Query() / get_posts()

Si solo queremos contar los elementos del menú sin los padres, podemos recopilar todos los objetos de publicación dentro de nuestro menú con:

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

donde $pids es una matriz de ID de publicación.

Entonces podemos hacer la siguiente 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 ) );

También hay un camino con:

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

o simplemente:

$count = $q->found_posts;

con el truco común, posts_per_page como 1, para reducir los datos obtenidos.

Ejemplo - wp_get_nav_menu_items()

Existen envoltorios útiles en el núcleo, como wp_get_nav_menu_items( $menu, $args ) donde $args son get_posts() argumentos.

Aquí hay una forma:

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

También 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 ) );

Ejemplo - filtro / ganchos

Hay muchos filtros / acciones que podríamos conectar para realizar el conteo, por ejemplo. El filtro wp_get_nav_menu_items . Incluso se engancha dentro del menú del navegador.

Incluso podríamos enganchar el wp_update_nav_menu que se activa cuando se actualiza el menú. Luego podríamos contar los elementos sin padres y almacenarlos, por ejemplo. como término metadatos.

Luego también hay varias formas con javascript.

Esperamos que esto te dé algunas ideas para llevar esto más lejos.

    
respondido por el birgire 03.07.2016 - 03:51
1

Gracias por la ayuda de birgire. Eso me dio mucho que pensar. Finalmente, se me ocurrió una solución utilizando un filtro que puedo contar el número de padres que tiene el menú. El único problema con este enfoque es que se ejecutará cada vez que se muestre un menú.

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

Cambie el "header_menu" a lo que sea la barra de navegación que desea verificar. Luego, puede almacenar esto en una opción y llamarlo cuando sea necesario.

    
respondido por el Chess Byte 05.07.2016 - 17:14

Lea otras preguntas en las etiquetas