Resaltar wp_nav_menu () Clase de ancestro sin hijos en la estructura de navegación?

29

( Nota de los moderadores: originalmente se tituló "wp_nav_menu Clase de antepasado sin hijos en la estructura de navegación")

Tengo un wp_nav_menu en mi encabezado que tenía tres páginas. Cuando estoy en una de esas páginas, el li que contiene esa página en el menú obtiene la clase .current_page_item . Estas tres páginas tienen plantillas y estas contienen consultas personalizadas para obtener todas las publicaciones de un determinado tipo de contenido. En efecto, los "niños" percibidos de esta página de nivel superior no son en realidad niños, solo son del tipo de contenido que he asociado con esa página de nivel superior mediante una plantilla.

Me gustaría que los elementos del menú de nivel superior obtengan una clase 'current-ancestor' cuando el usuario está navegando en una sola página de un tipo de publicación específica, nuevamente, asociado con esa página solo en una consulta personalizada en el archivo de plantilla.

Espero que tenga sentido. Si no, ¡hazme saber dónde te perdí! Aprecio mucho cualquier ayuda.

--Editado para detalles específicos: Por ejemplo, tengo una página estática llamada Talleres que utiliza una plantilla. Su babosa es talleres . La plantilla tiene una función personalizada get_posts y un bucle dentro de ella, que extrae y muestra todas las publicaciones de un tipo de contenido personalizado llamado talleres . Si hago clic en el título de uno de estos talleres, me dirijo al contenido completo de esa parte del contenido. La estructura de enlace permanente del tipo de publicación personalizada se establece en talleres / postname , por lo que el usuario lo ve, estos fragmentos de contenido son elementos secundarios de la página de Talleres, cuando en realidad son todos de un contenido. Tipo pero no relacionado con la página. Es esa brecha la que necesito para cerrar de manera efectiva en el menú, resaltando el elemento del menú "Talleres" cuando se navega por el contenido del tipo "taller".

Una vez más, espero que tenga sentido, ¡creo que dije 'taller' más de 20 veces en un párrafo!

    
pregunta Gavin 18.10.2010 - 20:42

7 respuestas

29

Hay una solución más simple. Olvídate de crear páginas para cada tipo de publicación solo para que puedas tener elementos de navegación, ya que, como has aprendido, WP no tiene forma de reconocer que los tipos personalizados que estás navegando están relacionados con esa página.

En su lugar, cree un enlace personalizado en Apariencia - > Menús. Simplemente coloque la URL que devolverá su tipo personalizado y asígnele una etiqueta, luego presione "Agregar al menú".

http://example.com/workshops/

o enlaces-no-bastante-bonitos:

http://example.com/?post_type=workshops

esto solo creará un botón de navegación que muestra todas las publicaciones con ese tipo de publicación personalizada, y también agregará la clase de elemento de menú actual cuando haya hecho clic en ese elemento de navegación, pero aún no lo hará. agregue la clase de navegación en cualquier URL que no sea esta

Luego, una vez que se haya creado, ingrese a la configuración para ese nuevo elemento e ingrese la barra del tipo de mensaje personalizado en el campo "Atributo del título" (también puede usar el campo de descripción, pero ese está oculto en el campo). opciones de la pantalla de administración por defecto).

Ahora, debe enlazar el filtro nav_menu_css_class (que se activa para cada elemento de navegación) y verificar si el contenido que se está viendo es del tipo de publicación indicado en su elemento de navegación personalizado:

add_filter('nav_menu_css_class', 'current_type_nav_class', 10, 2 );
function current_type_nav_class($classes, $item) {
    $post_type = get_query_var('post_type');
    if ($item->attr_title != '' && $item->attr_title == $post_type) {
        array_push($classes, 'current-menu-item');
    };
    return $classes;
}

En este caso, vamos a comprobar que el contenido del campo Atributo del título no esté vacío y si coinciden con el tipo de publicación actual que se está consultando. Si es así, agregamos la clase de elemento de menú actual a su matriz de clase, luego devolvemos la matriz modificada.

Puede modificar esto para que coincida simplemente con el título del elemento de navegación, pero si por alguna razón desea titular el elemento de navegación de manera diferente a la barra simple del tipo de publicación, utilizando el atributo Título o el campo Descripción le da esa flexibilidad .

Ahora, cada vez que esté viendo un solo elemento (o probablemente incluso listas de archivos) de un tipo de publicación que coincida con un elemento del menú de navegación, se le dará a la clase CSS el elemento de menú actual de la clase para que su resaltado funcione.

No se necesitan páginas ni plantillas de página ;-) La consulta de URL se encarga de buscar las publicaciones correctas. Su plantilla de bucle se encarga de mostrar el resultado de la consulta. Esta función se encarga de reconocer lo que se muestra y de agregar la clase CSS.

BONUS

Incluso puede automatizar el proceso usando wp_update_nav_menu_item , al generar automáticamente elementos de menú para todos sus tipos de publicaciones. Para este ejemplo, primero debería haber recuperado el $menu_id del menú de navegación al que desea agregar estos elementos.

$types = get_post_types( array( 'exclude_from_search' => false, '_builtin' => false  ), 'objects' );
foreach ($types as $type) {
    wp_update_nav_menu_item( $menu_id, 0, array(
        'menu-item-type' => 'custom',
        'menu-item-title' => $type->labels->name,
        'menu-item-url' => get_bloginfo('url') . '/?post_type=' . $type->rewrite['slug'],
        'menu-item-attr-title' => $type->rewrite['slug'],
        'menu-item-status' => 'publish'
        )
    );
}
    
respondido por el somatic 19.10.2010 - 07:25
4

en lugar de usar

  

$ post_type =   get_query_var ('post_type');

Es posible que desee probar:

  

$ post_type = get_post_type ();

Como algunas veces el tipo de publicación no está configurado en la var. de consulta. Este es el caso del tipo de publicación predeterminado de "publicación", por lo que si desea resaltar una publicación que se enumeró en una página de lista, deberá usarla. get_very_var () simplemente devuelve una cadena vacía para los tipos de publicación que no son personalizados.

add_filter('nav_menu_css_class', 'current_type_nav_class', 10, 2 );
function current_type_nav_class($classes, $item) {
    $post_type = get_post_type();
    if ($item->attr_title != '' && $item->attr_title == $post_type) {
        array_push($classes, 'current-menu-item');
    };
    return $classes;
}
    
respondido por el Eric 17.03.2011 - 15:18
2

@Somático - ¡eso es fantástico! Modifiqué un poco su código para que también funcione para una taxonomía específica (que estoy usando solo para el tipo de publicación relacionado). La idea es utilizar el atributo Título del elemento del menú para almacenar tanto el nombre del tipo de publicación Y el nombre de la taxonomía, separados por un punto y coma, y luego explotados por la función.

add_filter('nav_menu_css_class', 'current_type_nav_class', 10, 2 );
function current_type_nav_class($classes, $item) {

    # get Query Vars
    $post_type = get_query_var('post_type');  
    $taxonomy = get_query_var('taxonomy');

    # get and parse Title attribute of Menu item
    $title = $item->attr_title; // menu item Title attribute, as post_type;taxonomy
    $title_array = explode(";", $title);
    $title_posttype = $title_array[0];
    $title_taxonomy = $title_array[1];

    # add class if needed
    if ($title != '' && ($title_posttype == $post_type || $title_taxonomy == $taxonomy)) {
        array_push($classes, 'current-menu-item');
    };
    return $classes;
}
    
respondido por el tzeldin88 13.04.2011 - 02:12
2

Aquí está mi solución si quieres trabajar con wp_list_pages.

agrega esto en tus funciones.php

add_filter('page_css_class', 'my_page_css_class', 10, 2);
function my_page_css_class($css_class, $page){
    $post_type = get_post_type();
    if($post_type != "page"){
        $parent_page = get_option('page_for_custom_post_type-'.$post_type);
        if($page->ID == $parent_page)
            $css_class[] = 'current_page_parent';
    }
    return $css_class;
}

Ahora simplemente agregue en la tabla wp_options una nueva fila con un option_name de page_for_custom_post_type-xxxx y un option_value con la página ID quieres conectarte.

Quizás reconoció que ya existe una opción llamada page_for_posts . Si solo tiene 1 tipo de publicación personalizada, u puede configurar su página en /wp-admin/options-reading.php en el menú desplegable y la navegación establecerá la página actual correctamente.

Creo que WordPress Core debería ampliar esta sección con un menú desplegable para cada tipo de publicación registrada.

    
respondido por el Temo 13.06.2011 - 20:58
2

Decidí seguir con las páginas y usar el nombre de la plantilla de la página como una clase en el elemento de navegación. Esto me permite evitar saturar el atributo de título que no me gustó de algunas de las otras soluciones.

add_filter('nav_menu_css_class', 'mbudm_add_page_type_to_menu', 10, 2 );
//If a menu item is a page then add the template name to it as a css class 
function mbudm_add_page_type_to_menu($classes, $item) {
    if($item->object == 'page'){
        $template_name = get_post_meta( $item->object_id, '_wp_page_template', true );
        $new_class =str_replace(".php","",$template_name);
        array_push($classes, $new_class);
        return $classes;
    }   
}

También tengo clases de cuerpo agregadas a header.php

<body <?php body_class(); ?>>

Finalmente, esta solución requiere algunos css adicionales para aplicar el estado seleccionado / activo a los elementos del menú de navegación. Lo uso para mostrar archivos de taxonomía y tipos de publicaciones personalizados relacionados con la página como elementos secundarios de esta página:

/* selected states - include sub pages for anything related to products */
#nav-main li.current-menu-item a,
body.single-mbudm_product #nav-main li.lp_products a,
body.tax-mbudm_product_category #nav-main li.lp_products a,
#nav-main li.current_page_parent a{color:#c00;}
    
respondido por el Steve 15.10.2011 - 04:28
1

@Somatic - ¡Gran código! Yo mismo hice un cambio. Quería mantener el Atributo de Título para su propósito previsto, por lo que en lugar de eso, coloqué la barra de Tipo de publicación personalizada en las propiedades del menú avanzado Relación de enlace (XFN) que puede habilitar en Opciones de pantalla. He modificado

if ($item->attr_title != '' && $item->attr_title == $post_type) {

y lo cambié a

if ($item->xfn != '' && $item->xfn == $post_type) {
    
respondido por el user8899 23.09.2011 - 21:30
0

Buen trabajo somático.

Lamentablemente, no entiendo cómo puedes enumerar tus tipos de publicaciones personalizadas en una página de la forma en que lo explicas. Si no uso un page-portfolio.php y lo agrego a una página, todo lo que obtengo es la página 404.

Si me gusta lo que hace Gavin, he modificado un poco tu función para eliminar también "current_page_parent" de la página del blog como esta.

add_filter('nav_menu_css_class', 'current_type_nav_class', 10, 2);
function current_type_nav_class($css_class, $item) {
$post_type = get_query_var('post_type');

if (get_post_type()=='portfolio') {
    $current_value = "current_page_parent"; 
    $css_class = array_filter($css_class, function ($element) use ($current_value) { return ($element != $current_value); } );
}

if ($item->attr_title != '' && $item->attr_title == $post_type) {       
    array_push($css_class, 'current_page_parent');
};
return $css_class;

}

    
respondido por el Vayu 10.12.2010 - 13:36

Lea otras preguntas en las etiquetas