Выделение wp_nav_menu () Класс предков без детей в структуре Nav?

( Примечание модератора: Первоначально был назван «класс предков wp_nav_menu без детей в структуре навигации»)

У меня есть wp_nav_menu в моем заголовке, в котором было три страницы. Когда я нахожусь на одной из этих страниц, li, содержащий эту страницу в меню, получает класс .current_page_item. Эти три страницы имеют шаблоны, и эти шаблоны содержат пользовательские запросы для получения всех сообщений определенного типа контента. По сути, воспринимаемые «дети» этой страницы верхнего уровня на самом деле не являются дочерними, они только типа контента, который я связал с этой страницей верхнего уровня с использованием шаблона.

Мне бы хотелось, чтобы элементы меню верхнего уровня получали класс 'current-ancestor', когда пользователь просматривал одну страницу определенного типа сообщения, опять же связанную с этой страницей, только в пользовательский запрос в файле шаблона.

Надеюсь, что это имеет смысл - если нет, сообщите мне, где я потерял вас! Очень цените любую помощь.

- Отредактировано для специфики: Например, у меня есть статическая страница под названием Workshops , которая использует шаблон. Его слизень - это семинары . Шаблон имеет пользовательскую функцию get_posts и цикл внутри него, который вытягивает и отображает все записи пользовательского типа контента, называемые workshop . Если я нажму на один из названий этих семинаров, я доведен до полного содержания этого фрагмента контента. Структура permalink настраиваемого типа сообщений устанавливается на семинары / postname , так как пользователь видит это, эти фрагменты контента являются дочерними страницами Workshops, когда на самом деле все они одного контента тип, но не связанный со страницей. Это тот пробел, который мне нужно эффективно закрыть в меню, выделив пункт меню «Семинары» при просмотре содержимого «семинара» типа.

Опять же, надеюсь, что это имеет смысл, я думаю, что я сказал «семинар» более 20 раз в одном абзаце!

28 голосов | спросил Gavin 18 +04002010-10-18T22:42:13+04:00312010bEurope/MoscowMon, 18 Oct 2010 22:42:13 +0400 2010, 22:42:13

7 ответов


28

Есть более простое решение. Забудьте создать страницы для каждого типа сообщений, чтобы вы могли иметь навигационные элементы, потому что, как вы узнали, WP не имеет способа распознать, что пользовательские типы, которые вы просматриваете, связаны с этой страницей.

Вместо этого создайте пользовательскую ссылку в меню «Внешний вид» и «Меню». Просто поместите URL-адрес, который вернет ваш собственный тип и дайте ему ярлык, затем нажмите «Добавить в меню».

http://example.com/workshops/

или не-довольно-permalinks:

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

только это просто создаст кнопку навигации, которая отобразит все сообщения с этим пользовательским типом сообщения, а также добавит класс текущего меню, когда вы нажмете этот элемент навигации, но он пока не будет добавьте класс nav на любой URL-адрес, отличный от этого

Затем, как только он будет создан, перейдите в конфигурацию для этого нового элемента и введите пул пользовательского типа сообщения в поле «Атрибут заголовка» (вы также можете использовать поле описания, но оно скрыто в Параметры экрана администратора по умолчанию).

Теперь вам нужно подключить фильтр nav_menu_css_class (который запускается для каждого элемента навигации) и проверить, является ли просматриваемый контент типом сообщения, указанным в вашем настраиваемом навигационном элементе:

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

В этом случае мы будем проверять, что содержимое поля Атрибут заголовка не пуст и если они соответствуют текущему сообщению post_type. Если это так, мы добавляем класс current-menu-item в свой массив классов, а затем возвращаем измененный массив.

Вы можете изменить это, чтобы просто совместить заголовок элемента навигации, но если по какой-то причине вы хотите называть элемент навигации иначе, чем простой пул типа post, использование поля Title Attribute или Description дает вам такую ​​гибкость .

Теперь, когда вы просматриваете один элемент (или, возможно, даже архивные записи) типа сообщения, который соответствует элементу меню навигации, этому элементу будет присвоен элемент текущего меню класса CSS, чтобы ваша подсветка работала.

Никаких страниц или шаблонов страниц не требуется ;-) Запрос URL-адреса позаботится о получении правильных сообщений. Ваш шаблон цикла заботится о отображении вывода запроса. Эта функция заботится о распознавании того, что отображается, и добавлении класса CSS.

BONUS

Вы можете даже автоматизировать процесс, используя wp_update_nav_menu_item, автоматически создавая элементы меню для всех ваших типов сообщений. В этом примере вам нужно сначала получить $menu_id навигационного меню, в которое вы хотите добавить эти элементы.

$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'
        )
    );
}
ответил somatic 19 +04002010-10-19T09:25:38+04:00312010bEurope/MoscowTue, 19 Oct 2010 09:25:38 +0400 2010, 09:25:38
4

вместо

  

$ post_type =   get_query_var ( 'post_type');

Возможно, вы захотите попробовать:

  

$ post_type = get_post_type ();

Как раз тип сообщения не задается в запросе var. Это относится к по умолчанию post_type для «post», поэтому, если вы хотите выделить сообщение, указанное на странице со списком, вам нужно будет использовать это. get_very_var () просто возвращает пустую строку для типов сообщений, которые не являются обычными.

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;
}
ответил Eric 17 MarpmThu, 17 Mar 2011 17:18:20 +03002011-03-17T17:18:20+03:0005 2011, 17:18:20
2

@Somatic - это фантастика! Я немного изменил ваш код, чтобы он также работал для определенной таксономии (которую я использую только для связанного post_type). Идея состоит в том, чтобы использовать атрибут Title элемента меню для хранения как имени post_type И имени таксономии, разделенной точкой с запятой, а затем взорванной функцией.

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;
}
ответил tzeldin88 13 AMpWed, 13 Apr 2011 04:12:54 +040012Wednesday 2011, 04:12:54
2

Здесь мое решение, если вы хотите работать с wp_list_pages.

добавьте это в свои функции. 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;
}

Теперь просто добавьте в таблицу wp_options новую строку с option_name page_for_custom_post_type-xxxx и option_value с ID и хотите подключиться.

Возможно, вы узнали, что уже существует опция page_for_posts . Если у вас только 1 пользовательский тип сообщения, вы можете установить свою страницу в /wp-admin/options-reading.php в раскрывающемся списке, и навигация правильно установит текущую страницу.

Я думаю, что ядро ​​wordpress должно расширить этот раздел с выпадающим списком для каждого зарегистрированного типа записи.

ответил Temo 13 J0000006Europe/Moscow 2011, 22:58:05
2

Я решил придерживаться страниц и использовать имя шаблона страницы как класс для элемента nav. Это позволяет мне избежать загромождения атрибута title, который мне не понравился в отношении некоторых других решений.

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

У меня также есть классы body, добавленные в header.php

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

Наконец, для этого решения требуется дополнительное css для применения выбранного /активного состояния к вашим пунктам меню навигации. Я использую его для отображения таксономических архивов и пользовательских типов сообщений, связанных со страницей, как дети этой страницы:

/* 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;}
ответил Steve 15 +04002011-10-15T06:28:44+04:00312011bEurope/MoscowSat, 15 Oct 2011 06:28:44 +0400 2011, 06:28:44
1

@Somatic - Отличный код! Я сделал одно изменение сам. Я хотел сохранить атрибут заголовка по своему прямому назначению, поэтому вместо этого я поместил Slush Custom Post Type в свойства расширенного меню Link Relationship (XFN), которые можно включить в параметрах экрана. Я изменил

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

и изменил его на

if ($item->xfn != '' && $item->xfn == $post_type) {
ответил user8899 23 rdEurope/Moscowp30Europe/Moscow09bEurope/MoscowFri, 23 Sep 2011 23:30:40 +0400 2011, 23:30:40
0

Хорошая работа соматическая.

К сожалению, я не понимаю, как вы можете перечислить свои пользовательские типы сообщений на странице так, как вы объясните. Если я не использую page-portfolio.php и не добавляю его на страницу, все, что я получаю, это страница 404.

Если мне действительно нравится Gavin, я немного изменил вашу функцию, чтобы также удалить «current_page_parent» с этой страницы.

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;

}

ответил Vayu 10 FriEurope/Moscow2010-12-10T15:36:55+03:00Europe/Moscow12bEurope/MoscowFri, 10 Dec 2010 15:36:55 +0300 2010, 15:36:55

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132