Nav 구조에 자식이없는 wp_nav_menu () 상위 클래스?


30

( 중재자 노트 : 원래 제목은 "내비게이션 구조에 자식이없는 wp_nav_menu 상위 클래스")

나는이 wp_nav_menu거기에 세 페이지를했다 내 헤더. 해당 페이지 중 하나에있을 때 li메뉴에 해당 페이지를 포함하는 클래스가 클래스를 가져옵니다 .current_page_item. 이 세 페이지에는 템플릿이 있으며이 템플릿에는 특정 콘텐츠 유형의 모든 게시물을 가져 오는 사용자 지정 쿼리가 포함되어 있습니다. 실제로이 최상위 페이지 의 인식 된 "자식" 은 실제로 자식이 아니며 템플릿을 사용하여 해당 최상위 페이지와 연결 한 콘텐츠 유형일뿐입니다.

'current-ancestor'사용자가 템플릿 파일의 사용자 정의 쿼리에서만 해당 페이지와 관련된 특정 게시물 유형의 단일 페이지를 다시 탐색 할 때 최상위 레벨 메뉴 항목을 클래스에 추가 하고 싶습니다 .

이해가 되시길 바랍니다-그렇지 않다면 내가 어디에서 졌는지 알려주세요! 도움을 주셔서 감사합니다.

-특정 사항을 위해 편집 : 예를 들어 템플릿을 사용하는 Workshops 라는 정적 페이지 가 있습니다. 그것의 슬러그는 워크샵 입니다. 템플리트에는 사용자 정의 get_posts 함수가 있으며 그 안에 루프가 있으며, 이는 workshops 라는 사용자 정의 컨텐츠 유형의 모든 게시물을 가져와 표시합니다 . 이 워크샵 제목 중 하나를 클릭하면 해당 내용의 전체 내용으로 이동합니다. 사용자 정의 포스트 유형의 영구 링크 구조는 워크샵 /로 설정 postname사용자가 볼 수 있듯이 이러한 컨텐츠는 실제로 워크숍 페이지의 하위 항목입니다. 실제로 컨텐츠는 모두 하나의 컨텐츠 유형이지만 페이지와 관련이 없습니다. '워크샵'유형의 컨텐츠를 탐색 할 때 '워크샵'메뉴 항목을 강조 표시하여 메뉴에서 효과적으로 닫아야하는 차이입니다.

다시 말하지만, 그것이 의미가 있기를 바랍니다. 나는 한 단락에서 20 번 이상 '워크샵'이라고 말했습니다.


@Gavin- 당신이 성취하려고하는 것에 대한 몇 가지 더 구체적인 내용을 포함시킬 수 있습니까? 초록에서 답변을 시도하는 것보다 구체적인 용어로 답변을 작성하는 것이 더 쉽습니다. 또한 이와 관련된 URL 구조를 설명 할 수 있다면 도움이 될 것입니다.
MikeSchinkel

1
@Gavin- 도움이됩니다. 당신의 최상위 메뉴 옵션 그래서에서 워크샵의 목록입니다 "워크샵" (A)의 경로 /workshops/와 사용자가 워크샵 페이지에있는 경우 (예 /workshops/example-workshop/) 당신이 원하는 "워크샵" 메뉴 항목이 클래스 것으로 current_page_item지정, 올바른은?
MikeSchinkel

wp_nav_menu ()는 현재의 메뉴-조상 클래스를 노출
다니엘 삭스

답변:


29

더 간단한 해결책이 있습니다. 학습 한대로 WP는 탐색중인 사용자 정의 유형이 해당 페이지와 관련되어 있음을 인식 할 수있는 방법이 없기 때문에 탐색 항목을 가질 수 있도록 각 게시물 유형에 대한 페이지 작성은 잊어 버리십시오.

대신 모양-> 메뉴에서 사용자 정의 링크를 작성하십시오. 사용자 정의 유형을 반환하는 URL을 입력하고 레이블을 지정한 다음 "메뉴에 추가"를 누르십시오.

http://example.com/workshops/

또는 비-퍼머 링크 :

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

이것만으로도 해당 사용자 정의 게시물 유형의 모든 게시물을 표시하는 탐색 버튼이 생성되고 해당 탐색 항목을 클릭했을 때 현재 메뉴 항목 클래스가 추가되지만 아직 탐색 클래스가 추가되지는 않습니다. 이 이외의 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과 일치하는지 확인합니다. 그렇다면 현재 메뉴 항목 클래스를 클래스 배열에 추가 한 다음 수정 된 배열을 반환합니다.

탐색 항목의 제목과 간단히 일치하도록이 항목을 수정할 수 있지만 어떤 이유로 든 게시물 유형의 일반 슬러그와 다르게 탐색 항목의 제목을 지정하려는 경우 제목 속성 또는 설명 필드를 사용하면 유연성이 제공됩니다.

이제 탐색 메뉴 항목과 일치하는 게시물 유형의 단일 항목 (아마도 아카이브 목록)을 볼 때마다 해당 항목에 CSS 클래스 current-menu-item이 주어 지므로 강조 표시가 작동합니다.

페이지 나 페이지 템플릿이 필요 없습니다. ;-) URL 쿼리는 올바른 게시물을 가져옵니다. 루프 템플릿은 쿼리 출력을 표시합니다. 이 함수는 표시되는 내용을 인식하고 CSS 클래스를 추가합니다.

보너스

당신은 사용하여 프로세스를 자동화 할 수 있습니다 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'
        )
    );
}

그게 다야! 레이아웃이 해당 페이지에 대해 다소 복잡하고 페이지를 나열하지 않기 때문에 페이지 템플릿 만 사용하고 있지만 페이지 ID를 확인하기 위해 제공 한 필터를 계속 사용할 수 있습니다. 이 테마의 특성은 테마 옵션을 통해 페이지를 일치시킬 수 있다는 것입니다 ( '홈'은이 페이지이고 '정보'는이 페이지 등입니다). (놀랍게도 자세한) 도움에 감사드립니다!
Gavin

current_page_parent내 블로그 인 탐색 항목에서 를 제거해야 했지만 그렇지 않으면 작동했습니다. thx
pkyeck

$item->attr_titleTITLE을 뽑은 이후로이 기능이 작동하지 않았 으며 제목을 대문자로 썼습니다. 그래서 속성을 변경했으며 $item->post_name이제는 잘 작동합니다.
honk31

테마에 맞는 코드를 만들려고했지만 제대로 작동하지 않습니다. 사용자 정의 게시물 유형에있을 때 메뉴의 상위 항목에 적용된 수업이 없습니다 portfolio. 위의 코드를 사용했습니다. 무엇이 문제가 될 수 있습니까?
캐스퍼

4

사용하는 대신

$ post_type = get_query_var ( 'post_type');

시도해 볼 수 있습니다.

$ post_type = get_post_type ();

somtimes로 게시 유형이 쿼리 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;
}

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

2

wp_list_pages로 작업하려면 내 솔루션을 선택하십시오.

functions.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_namepage_for_custom_post_type-xxxx 이고 option_value가 있는 새 행을 추가하십시오.페이지 ID 연결하려는 u가 .

아마도 당신은 이미라는 옵션이 있음을 인식했습니다. page_for_posts . u에 사용자 정의 게시물 유형이 하나만있는 경우 드롭 다운의 /wp-admin/options-reading.php에서 페이지를 설정할 수 있고 탐색 기능이 current_page를 올바르게 설정합니다.

워드 프레스 코어는 등록 된 모든 게시물 유형에 대해 드롭 다운으로이 섹션을 확장해야한다고 생각합니다.


2

나는 페이지를 고수하고 페이지 템플릿 이름을 탐색 항목의 클래스로 사용하기로 결정했습니다. 이를 통해 다른 솔루션 중 마음에 들지 않은 제목 속성을 어지럽히 지 않아도됩니다.

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

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

이로 인해 다음과 같은 오류가 Warning: join() [function.join]: Invalid arguments passed in /home/path/to/wp-includes/nav-menu-template.php on line 76 발생했습니다.
Jeff K.

오 무슨 일인지 알 것 같아 if 문 내에서 $ classes를 반환하기 때문입니다. 단순히 return $classes외부로 이동 한 후 if위의 오류를 해결 하는 것 같습니다.
Jeff K.

1

@Somatic-훌륭한 코드! 나는 하나의 변화를했다. 제목 속성을 원래 목적에 맞게 유지하려고했기 때문에 대신 화면 옵션에서 활성화 할 수있는 XFN (링크 관계) 고급 메뉴 속성에 사용자 지정 게시물 유형 슬러그를 배치했습니다. 나는 수정했다

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

그것을로 변경

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

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;

}

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.