2010-07-17 13 views
8

Ho creato un tipo di post personalizzato di "portfolio" e una pagina con un modello che recupera tutti i post corrispondenti a tale tipo di post personalizzato.Gerarchia di tipi di post personalizzati Wordpress e evidenziazione del menu (current_page_parent)

Il problema è quando ho drill-down nel post vero e proprio, il posto sembra sedersi sotto 'blog' nel menu principale mettendo in evidenza (visualizza current_page_parent come classe)

L'url permalink è corretta: www.site .com/portfolio/post-slug

Ma il menu pensa che il genitore sia "blog".

Questo è ovviamente un problema gerarchico ma non so cosa fare per risolverlo.

risposta

10

Sembra che questo sia un problema con il codice core di Wordpress; il codice che genera le classi di menu aggiunge current_page_parent alla pagina Blog ovunque, tranne quando si visualizzano modelli di pagina statici.

(Questo è stato discusso nel passaggio http://core.trac.wordpress.org/ticket/13543).

È tuttavia possibile aggirare questo problema con un codice personalizzato utilizzando il filtro page_css_class. Ad esempio, aggiungere qualcosa in questo senso al functions.php (non al 100% testato):

function my_page_css_class($css_class, $page) { 
    if (get_post_type()=='portfolio' || is_page(57)) { 
     if ($page->ID == get_option('page_for_posts')) { 
      foreach ($css_class as $k=>$v) { 
       if ($v=='current_page_parent') unset($css_class[$k]); 
      } 
     } 
     if ($page->ID==57) { 
      $css_class[]='current_page_parent'; 
     } 
    } 
    return $css_class; 
} 
add_filter('page_css_class','my_page_css_class',10,2);

Sostituzione 57 con l'ID della pagina portafogli, naturalmente. Ciò rimuove current_page_parent quando si stampa la pagina del blog e aggiunge current_page_parent alla pagina del portfolio, quando si visualizza un singolo portfolio o si visualizza la pagina stessa del portfolio.

+0

+1 Trova eccellente, lieto di sentire in trac – TheDeadMedic

+1

L'ho fatto con CSS e classi di corpo per ora. Grazie per la funzione però. – Craig

+0

+1 piccolo piccolo frammento qui, mi ha salvato un sacco :) – Xavier

0

Ho fatto ancora un po 'di ricerche e ho trovato un altro modo per farlo.

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; 

}

ho avuto una qualche forma di aiuto questo post e poi modificato per rimuovere anche la classe "current_page_parent" dalla pagina del blog. https://wordpress.stackexchange.com/questions/3014/highlighting-wp-nav-menu-ancestor-class-w-o-children-in-nav-structure/3034#3034

Cordialmente Vayu

+0

Wups, questa risposta avrebbe dovuto venire dopo la mia domanda precedente di seguito ... –

3

biglietto WP: http://core.trac.wordpress.org/ticket/16382

function fix_blog_menu_css_class($classes, $item) { 
    if (is_tax('my-cat-tax') || is_singular('my-post-type') || is_post_type_archive('my-post-type')) { 
     if ($item->object_id == get_option('page_for_posts')) { 
      $key = array_search('current_page_parent', $classes); 
      if (false !== $key) 
       unset($classes[ $key ]); 
     } 
    } 

    return $classes; 
} 
add_filter('nav_menu_css_class', 'fix_blog_menu_css_class', 10, 2); 
0

Ecco una soluzione che ha funzionato per me, senza dover definire il mio tipo messaggio personalizzato o menu di id o la pagina id nel codice :

http://dtbaker.net/web-development/how-to-stop-wordpress-automatically-highlighting-the-blog-page-in-the-menu/

 
function dtbaker_wp_nav_menu_objects($sorted_menu_items, $args){ 
    // this is the code from nav-menu-template.php that we want to stop running 
    // so we try our best to "reverse" this code wp code in this filter. 
    /* if (! empty($home_page_id) && 'post_type' == $menu_item->type && empty($wp_query->is_page) && $home_page_id == $menu_item->object_id) 
      $classes[] = 'current_page_parent'; */ 

    // check if the current page is really a blog post. 
    //print_r($wp_query);exit; 
    global $wp_query; 
    if(!empty($wp_query->queried_object_id)){ 
     $current_page = get_post($wp_query->queried_object_id); 
     if($current_page && $current_page->post_type=='post'){ 
      //yes! 
     }else{ 
      $current_page = false; 
     } 
    }else{ 
     $current_page = false; 
    } 


    $home_page_id = (int) get_option('page_for_posts'); 
    foreach($sorted_menu_items as $id => $menu_item){ 
     if (! empty($home_page_id) && 'post_type' == $menu_item->type && empty($wp_query->is_page) && $home_page_id == $menu_item->object_id){ 
      if(!$current_page){ 
       foreach($sorted_menu_items[$id]->classes as $classid=>$classname){ 
        if($classname=='current_page_parent'){ 
         unset($sorted_menu_items[$id]->classes[$classid]); 
        } 
       } 
      } 
     } 
    } 
    return $sorted_menu_items; 
} 
add_filter('wp_nav_menu_objects','dtbaker_wp_nav_menu_objects',10,2); 
5

Ecco la mia versione ottimizzata/estesa delle soluzioni precedentemente suggerite, che è praticamente completamente automatizzata. Non sono necessari ulteriori CSS o attributi di menu.

Questa versione ottiene dinamicamente un elenco di tipi di post personalizzati e se il tipo di post corrente è un tipo di post personalizzato, rimuove la classe 'current_page_parent' da tutte le voci di menu.

Inoltre controlla ogni voce di menu per vedere se è per una pagina con un modello di pagina come "pagina- {custom_post_type_slug} .php", e in tal caso, aggiungerà la classe 'current_page_parent'.

La priorità del filtro è 1, come alcuni temi, sostituisce il file corrente_pagina/ecc. classi con una classe come 'active' (ad esempio 'roots' fa questo), quindi questo filtro deve essere eseguito prima.

Infine, fa uso di 3 variabili statiche poiché questa funzione viene ripetutamente chiamata e queste (ovviamente) rimangono invariate attraverso tutte le chiamate.

function theme_current_type_nav_class($css_class, $item) { 
    static $custom_post_types, $post_type, $filter_func; 

    if (empty($custom_post_types)) 
     $custom_post_types = get_post_types(array('_builtin' => false)); 

    if (empty($post_type)) 
     $post_type = get_post_type(); 

    if ('page' == $item->object && in_array($post_type, $custom_post_types)) { 
     if (empty($filter_func)) 
      $filter_func = create_function('$el', 'return ($el != "current_page_parent");'); 

     $css_class = array_filter($css_class, $filter_func); 

     $template = get_page_template_slug($item->object_id); 
     if (!empty($template) && preg_match("/^page(-[^-]+)*-$post_type/", $template) === 1) 
      array_push($css_class, 'current_page_parent'); 

    } 

    return $css_class; 
} 
add_filter('nav_menu_css_class', 'theme_current_type_nav_class', 1, 2); 

PS. Solo per segnalare una lacuna in tutte le soluzioni non CSS che ho visto finora, incluso il mio: Qualcosa non preso in considerazione sta evidenziando la voce di menu genitore/antenato di un oggetto che si collega ad una pagina che mostra i post dell'attuale tipo di messaggio personalizzato. Prendere in considerazione un tipo di messaggio personalizzato "prodotto" e un menu come:

Home Company News Contact 
     | 
     \--About Us 
     \--Products 

"Prodotti" è una pagina con un modello "page-Product.php" e mostra una panoramica di tutti i messaggi di tipo 'prodotto'. È evidenziato a causa della soluzione pubblicata. Tuttavia, anche la "Società" come genitore/antenato dovrebbe essere evidenziata, ma non lo è. Qualcosa da tenere a mente.

+0

grazie. Ciò ha risolto il mio problema con il post sul blog che riceve una classe attiva durante la visualizzazione di un tipo di post personalizzato – Mattijs