Realce wp_nav_menu () Classe de ancestral sem filhos na estrutura de navegação?

29

( Nota dos moderadores: foi originalmente intitulado "wp_nav_menu Classe ancestral sem filhos na estrutura de navegação")

Eu tenho um wp_nav_menu no meu cabeçalho que tinha três páginas nele. Quando estou em uma dessas páginas, o li que contém essa página no menu obtém a classe .current_page_item . Essas três páginas têm modelos e esses modelos contêm consultas personalizadas para obter todas as postagens de um determinado tipo de conteúdo. Com efeito, os "filhos" percebidos desta página de nível superior não são realmente crianças, eles são apenas um tipo de conteúdo associado a essa página de nível superior usando um modelo.

Gostaria que os itens de menu de nível superior obtivessem uma 'current-ancestor' de classe quando o usuário estivesse navegando em uma única página de um tipo de postagem específico, novamente associado a essa página somente em uma consulta personalizada no arquivo de modelo. / p>

Espero que faça sentido - se não, deixe-me saber onde eu perdi você! Muito aprecio qualquer ajuda.

- Editado para detalhes: Por exemplo, eu tenho uma página estática chamada Workshops que está usando um modelo. Sua lesma é oficinas . O modelo tem uma função get_posts personalizada e faz um loop dentro dele, o que puxa e exibe todas as postagens de um tipo de conteúdo personalizado chamado workshops . Se eu clicar em um dos títulos dessas oficinas, sou levado ao conteúdo completo desse conteúdo. A estrutura de permalink do tipo de postagem personalizada é definida como workshops / nome do post , de modo que, quando o usuário a vê, esses conteúdos são filhos da página Workshops, quando, na realidade, eles são todos de um conteúdo digite, mas não relacionado à página. É essa lacuna que eu preciso efetivamente fechar no menu, destacando o item de menu 'Workshops' ao navegar pelo conteúdo do tipo 'workshop'.

Mais uma vez, espero que faça sentido, eu acho que eu disse 'workshop' mais de 20 vezes em um parágrafo!

    
por Gavin 18.10.2010 / 20:42
fonte

7 respostas

29

Existe uma solução mais simples. Esqueça a criação de páginas para cada tipo de post apenas para que você possa ter itens de navegação, porque, como você aprendeu, o WP não tem como reconhecer que os tipos personalizados que você está navegando estão relacionados a essa página.

Em vez disso, crie um link personalizado em Menus de aparência e & gt ;. Basta colocar o URL que irá retornar o seu tipo personalizado e dar-lhe um rótulo, em seguida, pressione "Adicionar ao Menu".

http://example.com/workshops/

ou non-pretty-permalinks:

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

sozinho, basta criar um botão de navegação que exibe todas as postagens com esse tipo de postagem personalizado e também adicionará a classe de item de menu atual quando você clicou nesse item de navegação, mas ainda não adicione a classe nav em qualquer URL diferente desta

Em seguida, uma vez criado, vá para a configuração desse novo item e insira o espaçador do tipo de postagem personalizado no campo "Atributo de título" (você também pode usar o campo de descrição, mas esse está oculto na opções de tela de administrador por padrão).

Agora, você precisa conectar o filtro nav_menu_css_class (que é acionado para cada item de navegação) e verificar se o conteúdo visualizado é do tipo de postagem indicado em seu item de navegação 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;
}

Nesse caso, vamos verificar se o conteúdo do campo Atributo de Título não está vazio e se ele corresponde ao post_type atual que está sendo consultado. Em caso afirmativo, adicionamos a classe current-menu-item à sua matriz de classes e, em seguida, retornamos a matriz modificada.

Você poderia modificar isso para simplesmente corresponder ao título do item de navegação, mas se por algum motivo você quiser dar um título ao item de navegação de maneira diferente do slug simples do tipo de postagem, usar o campo Atributo de título ou Descrição oferece essa flexibilidade .

Agora, sempre que você estiver visualizando um único item (ou provavelmente até mesmo uma lista de arquivos) de um tipo de postagem que corresponda a um item de menu de navegação, esse item receberá o item de menu atual da classe CSS para que seu realce funcione.

Nenhuma página ou modelo de página é necessário ;-) A consulta de URL se encarrega de buscar as postagens certas. Seu modelo de loop cuida da exibição da saída da consulta. Esta função se encarrega de reconhecer o que está sendo mostrado e adicionar a classe CSS.

BÔNUS

Você pode até automatizar o processo usando wp_update_nav_menu_item , gerando itens de menu automaticamente gerados para todos os seus tipos de postagem. Para este exemplo, você precisaria primeiro ter recuperado o $menu_id do menu de navegação ao qual deseja adicionar esses itens.

$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'
        )
    );
}
    
por somatic 19.10.2010 / 07:25
fonte
4

em vez de usar

  

$ post_type =   get_query_var ('post_type');

Você pode querer tentar:

  

$ post_type = get_post_type ();

Como, às vezes, o tipo de postagem não é definido na consulta var. Este é o caso do post_type padrão de "post", então se você quiser destacar uma postagem listada de uma página de listagem, você precisará usá-la. get_very_var () apenas retorna uma string vazia para tipos de post que não são 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;
}
    
por Eric 17.03.2011 / 15:18
fonte
2

@Somatic - isso é fantástico! Eu modifiquei seu código um pouco, então ele também funciona para uma taxonomia específica (que eu estou usando apenas para o post_type relacionado). A idéia é usar o atributo Title do item de menu para armazenar o nome do post_type AND o nome da taxonomia, separado por um ponto-e-vírgula e depois explodido pela função.

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;
}
    
por tzeldin88 13.04.2011 / 02:12
fonte
2

Aqui, minha solução, se você quiser trabalhar com wp_list_pages.

adicione isso em suas funções.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;
}

Agora adicione à tabela wp_options uma nova linha com um nome_da_opção de page_for_custom_post_type-xxxx e um valor_de_opção com a página ID u deseja se conectar.

Talvez você tenha reconhecido que já existe uma opção chamada page_for_posts . Se você tiver apenas 1 tipo de postagem personalizada, você pode definir sua página em /wp-admin/options-reading.php no menu suspenso e a navegação irá definir a current_page corretamente.

Acho que o núcleo do wordpress deve estender essa seção com um menu suspenso para cada tipo de postagem registrado.

    
por Temo 13.06.2011 / 20:58
fonte
2

Eu decidi ficar com as páginas e usar o nome do modelo de página como uma classe no item de navegação. Isso me permite evitar o atributo title que eu não gostei em algumas das outras soluções.

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

Eu também tenho classes de corpo adicionadas ao header.php

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

Por fim, essa solução requer algum css extra para aplicar o estado selecionado / ativo aos itens do menu de navegação. Eu uso para mostrar arquivos de taxonomia e tipos de postagem personalizados relacionados à página como filhos desta 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;}
    
por Steve 15.10.2011 / 04:28
fonte
1

@Somatic - Ótimo código! Eu fiz uma mudança eu mesmo. Eu queria manter o Atributo de Título para o propósito pretendido, então, em vez disso, coloquei o slug Custom Post Type nas propriedades avançadas do menu Link Relationship (XFN) que você pode ativar em Opções de Tela. Eu modifiquei

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

e alterou para

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

Bom trabalho, somático.

Infelizmente, não entendo como você pode listar seus tipos de postagem personalizados em uma página da maneira que você explica. Se eu não usar um page-portfolio.php e adicioná-lo a uma página, tudo que eu obtenho é a página 404.

Se eu gosto do Gavin, modifiquei a sua função para remover também o "current_page_parent" da página do 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;

}

    
por Vayu 10.12.2010 / 13:36
fonte