web-dev-qa-db-fra.com

Type de message personnalisé. Élément de menu .current ne s'applique pas à la page d'archive Type de message personnalisé

Je travaille avec des types de publication personnalisés et j'ai eu des problèmes avec le menu de navigation ne pas obtenir le .current-menu-item sur mon élément de menu custom post archive page. En fait, lorsque je me trouvais sur cette page ou sur l'un des custom posts, au lieu de l'élément de menu cpt archive obtenant la classe actuelle, l'élément de menu pointant sur les articles recevait le .current-menu-item (page de blog dans mon cas).

Après plusieurs heures, google, tests et hacks, j’ai trouvé ce fil sur wordpress et voici une copie de la version modifiée du correctif:

// As of WP 3.1.1 addition of classes for css styling to parents of custom post types doesn't exist.
// We want the correct classes added to the correct custom post type parent in the wp-nav-menu for css styling and highlighting, so we're modifying each individually...
// The id of each link is required for each one you want to modify
// Place this in your WordPress functions.php file

function remove_parent_classes($class)
{
  // check for current page classes, return false if they exist.
    return ($class == 'current_page_item' || $class == 'current_page_parent' || $class == 'current_page_ancestor'  || $class == 'current-menu-item') ? FALSE : TRUE;
}

function add_class_to_wp_nav_menu($classes)
{
     switch (get_post_type())
     {
        case 'artist':
            // we're viewing a custom post type, so remove the 'current_page_xxx and current-menu-item' from all menu items.
            $classes = array_filter($classes, "remove_parent_classes");

            // add the current page class to a specific menu item (replace ###).
            if (in_array('menu-item-171', $classes))
            {
               $classes[] = 'current_page_parent';
         }
            break;
     }
    return $classes;
}
add_filter('nav_menu_css_class', 'add_class_to_wp_nav_menu');

Cette solution fonctionne lorsque nous utilisons l'identifiant d'élément de menu, mais je la trouve très moche et impossible à utiliser pour le développement de plugins ...

Toute autre idée pour sélectionner l'élément de menu correspondant à la page d'archivage des publications personnalisées lorsque nous sommes sur la page d'archivage ou sur l'une des publications personnalisées de manière plus propre?

_ {En d'autres termes, un modèle d'archive n'est pas supposé sélectionner son propre élément de menu par défaut?} _

Je n'avais jamais pensé que mettre en évidence un élément dans le menu de navigation wordpress aurait pu être un problème avec les types de publication personnalisés, je suis un peu déçu. Quoi qu'il en soit, voici quelques-uns des codes que j'utilise pour gérer mes messages personnalisés (artiste):

artist.php :

/****************************************************************
* Custom Post Type
****************************************************************/

add_action( 'init', 'custom_post_artist' );
function custom_post_artist()
{
  $labels = array(
    [...]
    );

  register_post_type( 'artist',
    array(
      'labels' => $labels,
      'public' => true,
      'menu_position' => 15,
      'supports' => array( 'title', 'editor', 'comments', 'thumbnail', 'revisions', 'excerpt'),
      'show_in_nav_menus' => true,
      'show_in_menu' => true,
      'taxonomies' => array( 'artist_genre', 'artist_music_type' ),
      'has_archive' => 'artistes',
      'rewrite' => array( 'slug' => __('artistes', 'ppdev'), 'with_front' => False )
      )
    );
}

/****************************************************************
* Templates
****************************************************************/

add_filter( 'template_include', 'include_tpl_function', 1 );
function include_tpl_function( $template_path )
{
  if ( get_post_type() == 'artist' )
  {
    if ( is_single() )
    {
      // checks if the file exists in the theme first,
      // otherwise serve the file from the plugin
      if ( $theme_file = locate_template( array('single-artist.php') ) )
      {
        $template_path = $theme_file;
      }
      else
      {
        $template_path = ARTIST_PATH . 'templates/single-artist.php';
      }
    } 
    else if( is_archive() )
    {
      if ( $theme_file = locate_template( array('archive-artist.php') ) )
      {
        $template_path = $theme_file;
      }
      else
      {
        $template_path = ARTIST_PATH . 'templates/archive-artist.php';
      }
    }
  }
  return $template_path;
}

Page de modèle d'archive très basique:

archive-artist.php :

<section id="primary">
  <div id="content" role="main">
    <?php if ( have_posts() ) : ?>
    <header class="page-header">
      <h1 class="page-title">Latest artists</h1>
    </header>

      <!-- Start the Loop -->         
      <?php while ( have_posts() ) : the_post();

      $thumbnail_attr = array(
        'class' => "aligncenter",
        'alt' => get_the_title()
      );

      <h2>
        <a title="<?php the_title(); ?>" href="<?php the_permalink(); ?>">
          <?php the_title(); ?>
        </a>
      </h2>

      if ( has_post_thumbnail() ) : ?>
          <a title="<?php the_title(); ?>" href="<?php the_permalink(); ?>">
            <?php the_post_thumbnail( 'full', $thumbnail_attr ); ?>
          </a>            
      <?php endif; ?>
      <?php endwhile; ?>

     <!-- Display page navigation -->
   <?php global $wp_query;
   if ( isset( $wp_query->max_num_pages ) && $wp_query->max_num_pages > 1 ) { ?>
   <nav id="<?php echo $nav_id; ?>">
     <div class="nav-previous"><?php next_posts_link( '<span class="meta-nav">&larr;</span> Previous artists' ) ); ?></div>
     <div class="nav-next"><?php previous_posts_link( 'Next artists <span class= "meta-nav">&rarr;</span>' ); ?></div>
   </nav>
   <?php };
  endif; ?>
 </div>
</section>

_ {Remarque: a également été testé avec vingt-douze thèmes et le même numéro} _

2
GabLeRoux

J'ai trouvé une réponse en cherchant dans des publications et des liens similaires. J'ai ajouté une ligne pour répondre à mes besoins (je voulais éviter que ma page de blog ne soit mise en évidence lors d'une publication personnalisée). Voir cette ligne: unset($classes[array_search('current_page_parent',$classes)]);

Solution

function add_parent_url_menu_class( $classes = array(), $item = false ) {
  // Get current URL
  $current_url = current_url();

  // Get homepage URL
  $homepage_url = trailingslashit( get_bloginfo( 'url' ) );

  // Exclude 404 and homepage
  if( is_404() or $item->url == $homepage_url )
    return $classes;

  if ( get_post_type() == "artist" )
  {
    unset($classes[array_search('current_page_parent',$classes)]);
    if ( isset($item->url) )
      if ( strstr( $current_url, $item->url) )
        $classes[] = 'current-menu-item';
  }

  return $classes;
}

function current_url() {
  // Protocol
  $url = ( 'on' == $_SERVER['HTTPS'] ) ? 'https://' : 'http://';
  $url .= $_SERVER['SERVER_NAME'];

  // Port
  $url .= ( '80' == $_SERVER['SERVER_PORT'] ) ? '' : ':' . $_SERVER['SERVER_PORT'];
  $url .= $_SERVER['REQUEST_URI'];

  return trailingslashit( $url );
}
add_filter( 'nav_menu_css_class', 'add_parent_url_menu_class', 10, 3 );

La source

Je ne suis pas un fan de cette réponse car il utilise l'URL pour comparer l'élément dans l'élément de menu, mais celui-ci fonctionnera correctement pour différents ID de menu et peut être utilisé dans un plugin. J'espère que cela aide quelqu'un, j'ai perdu quelques heures pour quelque chose que je considère comme un bug de wordpress.

2
GabLeRoux

Ma solution à ce problème lors de l'extension du Walker_Nav_Menu était de ne pas vérifier si current_page_parent quand C.P.T. J'ai identifié C.P.Ts après cette stackexchange post.

Cela ne résout pas entièrement le problème car j'utilise current_page_item pour les éléments de menu parent C.P.T, mais cela permet d'obtenir le résultat souhaité. Voici ma class.

class My_Menu extends Walker_Nav_Menu {  

  public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {

    $post_type = get_post_type();
    $class_names = '';

    // Check if post_type - $item->attr_title returns the WP Menu custom link Title Attribute
    $class_names .= ($item->attr_title != '' && $item->attr_title == $post_type || in_array("current_page_item", $item->classes)) ? 'current_page_item' : '';

    // Prevent Blog menu item from getting the current_page_parent class when Custom Post Type
    if(!is_post_type_archive() && !is_singular(array( 'custom-one', 'custom-two'))){
    $class_names .= in_array("current_page_parent", $item->classes) ? ' current_page_parent' : '';
    }

    $id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );
    $id = $id ? ' id="' . esc_attr( $id ) . '"' : '';
    $class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';

    $output .= '<li' . $id . $class_names .'>';

    $atts = array();
    $atts['title']  = ! empty( $item->attr_title ) ? $item->attr_title : '';
    $atts['target'] = ! empty( $item->target )     ? $item->target     : '';
    $atts['rel']    = ! empty( $item->xfn )        ? $item->xfn        : '';
    $atts['href']   = ! empty( $item->url )        ? $item->url        : '';

    $atts = apply_filters( 'nav_menu_link_attributes', $atts, $item, $args );

    $attributes = '';
    foreach ( $atts as $attr => $value ) {
        if ( ! empty( $value ) ) {
            $value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value );
            $attributes .= ' ' . $attr . '="' . $value . '"';
        }
    }
    $item_output = $args->before;
    $item_output .= '<a'. $attributes .'>';
    $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
    $item_output .= '</a>';

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

  public function end_el( &$output, $item, $depth = 0, $args = array() ) {
    $output .= "</li>\n";
  }

} // Walker_Nav_Menu
1
user1575949