¿Cómo obtener el ID de la página a la que enlaza un elemento del menú?

31 mar 2011, 12:44:47
Vistas: 30.2K
Votos: 10

Actualmente estoy usando un walker personalizado para personalizar la salida de wp_nav_menu(), y estoy tratando de agregar información adicional a las etiquetas <a>.

Lo que quiero que se vea como salida para cada enlace del menú es:

<a class="boxPAGEID" href="#">Página Acerca de Mí</a>

Donde PAGEID es el ID de la página a la que estoy enlazando.

La razón es porque estoy desarrollando un tema que abre el contenido de la página en lightboxes, que se activan por la clase en la etiqueta.

A continuación está el código del walker personalizado en mi archivo functions.php (después del código señalaré el área donde estoy teniendo problemas):

class description_walker extends Walker_Nav_Menu
{

      function start_el(&$output, $item, $depth, $args)
      {
           global $wp_query;     
           $pageid = $wp_query->post->ID;

           $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

           $class_names = $value = '';

           $classes = empty( $item->classes ) ? array() : (array) $item->classes;

           $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
           $class_names = ' class="'. esc_attr( $class_names ) . '"';

           $output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $class_names .'>';

           $attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
           $attributes .= ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
           $attributes .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
           $attributes .= ! empty( $item->url )        ? ' href="'   . '#' .'"' : '';

           $prepend = '<strong>';
           $append = '</strong>';
           $description  = ! empty( $item->description ) ? '<span>'.esc_attr( $item->description ).'</span>' : '';

           if($depth != 0)
           {
                     $description = $append = $prepend = "";
           }

            $item_output = $args->before;
            $item_output .= '<a'. $attributes . 'class="box' . $pageid . '"' .'>';
            $item_output .= $args->link_before .$prepend.apply_filters( 'the_title', $item->title, $item->ID ).$append;
            $item_output .= $args->link_after;
            $item_output .= '</a>';
            $item_output .= $args->after;

            $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );

            if ($item->menu_order == 1) {
                $classes[] = 'first';
            }

            }
}

Hacia el final hay un par de líneas que comienzan con $item_output. La segunda línea es donde estoy tratando de generar el ID de la página:

$item_output .= '<a'. $attributes . 'class="box' . $pageid . '"' .'>';

Donde $pageid está definido según:

global $wp_query;    
$pageid = $wp_query->post->ID;

Esto me da un único ID fijo para todos los enlaces generados.

Alternativamente, en lugar de $pageid intenté usar $item->ID, pero eso me dio el ID del elemento del menú en su lugar.

¿Alguna sugerencia?

1
Comentarios

Si hay alternativas al ID de la página, eso también funcionaría. Inicialmente intenté usar $item->url, pero la URL no funciona como nombre de clase. El título de la página solo funciona si no hay espacios, y los otros atributos no se generan por defecto.

Raiman Au Raiman Au
31 mar 2011 12:54:55
Todas las respuestas a la pregunta 3
2
27

El ID de página (o ID de objeto, ya que un elemento de menú puede enlazar a cualquier objeto) se almacena en la tabla postmeta, con la clave _menu_item_object_id. Por lo tanto, puedes obtener el ID de la página con el siguiente código:

get_post_meta( $item->ID, '_menu_item_object_id', true );
5 abr 2011 17:36:52
Comentarios

¡JAN!!!!! ¡Esto funcionó! Perdón por la respuesta tardía, pero tu sugerencia hizo el truco. ¡Eres fabuloso/a! ¡Gracias!

Y para que conste para aquellos que no están seguros de qué hacer:

Cambié el $pageid = $wp_query->post->ID; al inicio de la página por $pageid = get_post_meta( $item->ID, '_menu_item_object_id', true );

Raiman Au Raiman Au
15 abr 2011 07:42:40

@Jan Fabry: ¡Excelente!!! Me ahorraste tiempo.. ¡Genial!!!

Sanjay Khatri Sanjay Khatri
20 jul 2012 11:17:18
1

El PAGEID está disponible en $item->object_id, si $item->object es page.

$item->object contiene el tipo de elemento del menú. Los valores posibles son page, post, category,...

$item->object_id contiene el ID del objeto.

Descubrí esto haciendo var_dump($item) en WordPress 5.4.2.

17 jun 2020 12:01:31
Comentarios

Esta será la respuesta aceptada ya que es más eficiente que el enfoque con get_post_meta.

turboLoop turboLoop
8 jul 2022 12:32:21
1
-1

No pude revisar tu código en profundidad pero para crear un menú tal vez deberías usar get_pages...

http://codex.wordpress.org/Function_Reference/get_pages

<?php 
  $pages = get_pages(); 
  foreach ($pages as $pagg) {
    $option = '<a class="box' . $pagg->ID . '" href="#">';
    $option .= $pagg->post_title;
    $option .= '</a>';
    echo $option;
  }
 ?>
31 mar 2011 16:05:42
Comentarios

¡Gracias por la sugerencia, Serdar! Lamentablemente esto no funcionará porque necesito que el menú pueda ser controlado desde la sección apariencia > menú en el panel de administración. Por eso estoy usando wp_menu_nav y no get_pages.

Raiman Au Raiman Au
1 abr 2011 07:38:41