it-swarm.com.de

Benutzerdefinierter Beitragstyp. Aktuelles Menüelement, das auf der Archivseite für individuelle Beiträge nicht angewendet wird

Ich arbeite mit benutzerdefinierten Beitragstypen und habe Probleme mit dem Navigationsmenü, bei dem der .current-menu-item nicht in meinem custom post archive page-Menüelement angezeigt wird. Wenn ich mich auf dieser Seite oder einem der custom posts befand, erhielt der Menüpunkt, der auf die Artikel zeigte, den .current-menu-itemin meinem Fall die Blog-Seite), anstatt dass der Menüpunkt cpt archive die aktuelle Klasse abrief.

Nach mehreren Stunden, Google, Tests und Hacks fand ich diesen Thread auf WordPress und hier ist eine Kopie der überarbeiteten Version des Workaround-Fixes:

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

Diese Lösung funktioniert, wenn wir den Menüpunkt id verwenden, aber ich finde es sehr hässlich und es ist unmöglich, dies für die Plugin-Entwicklung zu verwenden ...

Irgendwelche _ (andere Ideeum den Menüpunkt auszuwählen, der der Archivseite der benutzerdefinierten Beiträge entspricht, wenn wir uns auf der Archivseite oder auf einem der benutzerdefinierten Beiträge auf eine sauberere Weise befinden?

Mit anderen Worten, eine Archivvorlage soll keinen eigenen Menüeintrag auswählen?

Ich hätte nie gedacht, dass das Hervorheben eines Elements im WordPress-Navigationsmenü ein Problem mit benutzerdefinierten Beitragstypen sein könnte. Ich bin ein bisschen enttäuscht. Wie auch immer, hier sind einige Codebeispiele, mit denen ich meine benutzerdefinierten Posts (Künstler) verwalte:

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

Sehr einfache Archivvorlagen-Seite:

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>

Anmerkung: Auch getestet mit dem zwanzigsten Thema und der gleichen Ausgabe

2
GabLeRoux

Ich habe eine Antwort gefunden, indem ich in ähnlichen Beiträgen und Links gesucht habe. Ich habe eine Zeile hinzugefügt, die meinen Anforderungen entspricht (ich wollte verhindern, dass meine Blog-Seite in einem benutzerdefinierten Beitrag hervorgehoben wird). Siehe folgende Zeile: unset($classes[array_search('current_page_parent',$classes)]);

Lösung

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

Quelle

Ich bin kein Fan dieser Antwort, da sie die URL verwendet, um das Element im Menüelement zu vergleichen, aber diese funktioniert gut für verschiedene Menü-IDs und kann in einem Plugin verwendet werden. Hoffe, es hilft jemandem, verlor ein paar Stunden für etwas, das ich für einen WordPress-Bug halte.

2
GabLeRoux

Meine Lösung für dieses Problem beim Erweitern des Walker_Nav_Menu bestand darin, zu überspringen, ob current_page_parent beim C.P.T. Ich habe nach diesem stackexchange post C.P.Ts identifiziert.

Dies löst das Problem nicht vollständig, da ich current_page_item für übergeordnete C.P.T-Menüelemente verwende, aber das gewünschte Ergebnis erzielt. Hier ist meine 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