wp_nav_menu에서 메뉴 항목을 동적으로 제외


17

사용자 정의 메뉴에서 탐색 메뉴 항목을 제외 / 제거하는 방법에 대한 정보를 찾으려고했지만 찾은 유일한 스레드 에는 유용한 답변이 없었습니다.

1. 배경 :

내 사이트에서 WP 사용자 정의 메뉴 (wp_nav_menu)와 jqDock 을 사용하여 Dock 메뉴를 구성 했습니다. jqDock은 마술처럼 작동하기 위해 연속적인 이미지 또는 이미지 링크가 필요하기 때문에 사용자 지정 워커를 사용하여 탐색 메뉴 HTML 출력이 다음과 같이 보입니다.

<div id="menu-first" class="nav">
<a><img src="http://path/to/image-1.png"/></a>
<a><img src="http://path/to/image-2.png"/></a>
<a><img src="http://path/to/image-3.png"/></a>
etc...
</div>

내 맞춤 워커의 코드는 다음과 같습니다.

class custom_nav_walker extends Walker_Nav_Menu 
{
    var $tree_type = array( 'post_type', 'taxonomy', 'custom' );
    var $db_fields = array( 'parent' => 'menu_item_parent', 'id' => 'db_id' );

    function start_lvl(&$output, $depth) {
        $indent = str_repeat("\t", $depth);
        $output .= "\n$indent<ul class=\"sub-menu\">\n";
    }

    function end_lvl(&$output, $depth) {
        $indent = str_repeat("\t", $depth);
        $output .= "$indent</ul>\n";
    }

    function start_el(&$output, $item, $depth, $args) {
        global $wp_query;
        $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

        $class_names = $value = '';

        $classes = empty( $item->classes ) ? array() : (array) $item->classes;
        $classes[] = 'menu-item-' . $item->ID;

        $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) );
        $class_names = ' class="' . esc_attr( $class_names ) . '"';

        $id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );
        $id = strlen( $id ) ? ' id="' . esc_attr( $id ) . '"' : '';

        //$output .= $indent . '<li' . $id . $value . $class_names .'>';

        $attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
        $attributes .= ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
        $attributes .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
        $attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'"' : '';

        $description  = ! empty( $item->description ) ? esc_attr( strtolower( $item->description )) : '';
        $item_title   = ! empty( $item->attr_title )  ? esc_attr( $item->attr_title ) : '';

        if ( strpos($description, ';') !== false ) {
        $description_array = explode (';', $description);
            $image_name = $description_array[0];
            $image_alt = $description_array[1];
        } else {
            $image_name = $description;
            $image_alt = $item_title;
        }

        $item_output = $args->before;
        $item_output .= '<a'. $attributes .'>';
        $item_output .= $args->link_before .'<img src="'.get_bloginfo('template_url').'/images/skin1/'.$image_name.'" alt="'.$image_alt.'" title="'.$item_title.'" />'.$args->link_after;
        $item_output .= '</a>';
        $item_output .= $args->after;

        $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
    }

    function end_el(&$output, $item, $depth) {
        $output .= "";
    }

}

그런 다음 jqDock 스크립트는 메뉴 ID ( 'menu-first')를 잡고 wp_nav_menu 출력을 Dock 메뉴로 바꿉니다. Dock 메뉴의 HTML 출력은 jqDock을로드 할 때 지정된 옵션에 따라 변경됩니다.

2. 질문 :

사용자의 사이트 위치에 따라 특정 메뉴 항목을 표시하지 않으려 고합니다 (즉, 제외). 예를 들어, 사용자가 집에 없을 때만 홈 항목을 표시하고 그가있을 때만 임의 게시물 항목을 표시하고 싶습니다.

3. 폐기 된 솔루션 :

ㅏ. 다중 메뉴 : 여러 메뉴를 등록 및 생성 한 다음 조건부로 호출하면 작동 할 수 있습니다. 그러나 여러 가지 이유로 이것이 이상적이고 깨끗한 해결책이라고 생각하지 않습니다. 또한 여러 메뉴를 유지 관리하거나 업데이트하기가 쉽지 않습니다.

비. 정규식 검색 및 바꾸기 : HTML 출력이 수정되어 jqDock 옵션을 변경할 때마다 바늘 매개 변수 를 변경해야 할 수 있습니다 .

씨. CSS 'display'속성 : CSS display 속성을 통해 항목을 숨기는 것은 작동하지만 jqDock 메뉴 출력에 적용되어야하기 때문에 메뉴의 시각적 렌더링에 영향을줍니다.

4. 실패한 해결책 :

ㅏ. wp_nav_menu_items로 필터링 : '$ items'변수 (문자열)를 포착하고 다음 코드로 조건부 태그를 통해 다른 값을 할당하려고했습니다.

function userf_dynamic_nav_menu ($items) {
    $items_array_home = explode('<a', $items);
    $items_array_nothome = $items_array_home;

    unset($items_array_home[1]);
    unset($items_array_nothome[2]);

    $items_home = implode('<a', $items_array_home);
    $items_nothome = implode('<a', $items_array_nothome);

    if ( is_home() ) {
        $items = $items_home;
    } else {
        $items = $items_nothome;
    }
    return $items;
}
add_filter('wp_nav_menu_first_items', 'userf_dynamic_nav_menu');

메뉴 항목이 변경되기 때문에 부분적으로 만 작동하지만 조건부 태그는 무시됩니다. 필터가 적용되는 순간 때문에 이것이 의미가 있다고 생각합니다.

비. 사용자 정의 탐색 메뉴 기능 : $ defaults 배열에 제외 인수를 추가하고이 약간 수정 된 코드를 사용 wp_list_pages하여 추가 인수를 채울 수있는 사용자 정의 탐색 메뉴 기능을 작성하려고했습니다 .

$exclude_array = ( $args->exclude ) ? explode(',', $args->exclude) : array();
$args->exclude = implode( ',', apply_filters('wp_nav_menu_excludes', $exclude_array) );

어떤 아이디어?


커스텀 워커 어린이 클래스를 보여줄 수 있습니까?
soulseekah

안녕하세요 Souleseekah, 난 그냥 내 원래 게시물에 추가했습니다. 감사!
Marventus

나는 exclude인수 를 전달하려고 생각 했지만 wp_list_pages다른 많은 WP 함수와 wp_nav_menu는 달리 인수를 포함하지 않았습니다. 따라서 메뉴를 호출 할 때 또는 워커에서 하나를 지정하더라도 내부 wp_nav_menu에서 픽업되지 않습니다 .
Marventus

미안, 내가 쓸 때 똑바로 생각하지 않고 즉시 삭제했습니다.
soulseekah

걱정하지 마세요!
Marventus

답변:


26

방법 1

다음과 같이 일부 제외 인수를 저장하기 위해 사용자 정의 Walker에 생성자를 추가 할 수 있습니다.

class custom_nav_walker extends Walker_Nav_Menu {
    function __construct( $exclude = null ) {
        $this->exclude = $exclude;
    }

    function skip( $item ) {
        return in_array($item->ID, (array)$this->exclude);
        // or
        return in_array($item->title, (array)$this->exclude);
        // etc.
    }

    // ...inside start_el, end_el
    if ( $this->skip( $item ) ) return;
}

또는 생성자를 삭제하고 $exclude속성을 워커로 전달하기 전에 설정하십시오 wp_nav_menu().

$my_custom_nav_walker = new custom_nav_walker;
$my_custom_nav_walker->exclude = array( ... );

제외 대상에 따라 제외 양식에 올바른 양식을 제공하십시오.

방법 2

이것은 wp_get_nav_menu_items필터 에 연결 하여이 작업을 수행하는 방법 입니다.

function wpse31748_exclude_menu_items( $items, $menu, $args ) {
    // Iterate over the items to search and destroy
    foreach ( $items as $key => $item ) {
        if ( $item->object_id == 168 ) unset( $items[$key] );
    }

    return $items;
}

add_filter( 'wp_get_nav_menu_items', 'wpse31748_exclude_menu_items', null, 3 );

참고 : object_id메뉴가 가리키는 개체 인 반면 ID메뉴 ID는 다릅니다.

네 생각을 말해봐.


감사! 작동 할 수도 있습니다. 시도해보고 알려 드리겠습니다.
Marventus

나는 constuctor 접근법을 시도했지만, 무엇을 시도하더라도 in_array함수에 대해 "두 번째 인수에 잘못된 데이터 유형"오류가 계속 발생 합니다. 내가 뭔가 잘못하고 있습니까?
Marventus

$exclude속성은 배열해야합니다. 따라서 배열을 생성자에 전달하거나 내 답변에서 업데이트 된 코드를 확인하십시오. 특히 $this->exclude배열이 전달되지 않는 경우에 대한 유형 변환입니다 .
soulseekah

그것에 대해 죄송합니다 : 내 기능에 오타가있었습니다. 방금 $exclude = array ('4', '7');슬러그를 사용해 보았지만 워커 출력에 영향을 미치지 않습니다. 두 번째 방법을 시도하고 알려 드리겠습니다.
Marventus

아니, 그건 작동하지 않았다. 나는 이것을 알아 내려고 노력하면서 뇌가 죽었다고 생각한다. 그래서 "... performance", :-)
Marventus

0

이게 도움이 되니

$exclude_array = ( $args->exclude ) ? explode(',', $args->exclude) : array();
$args->exclude = implode( ',', apply_filters('wp_nav_menu_excludes', $exclude_array) );

예로서

< ?php wp_nav_menu( array( 'container_class' => 'menu-header', 'theme_location' => 'primary', 'exclude' => '66' ) ); ?>

안녕하세요 Saq, 작동하지 않는 솔루션 중 하나는 사용자 정의 nav_menu 함수를 만들고 해당 코드를 함수의 기본값에 대한 추가 인수로 추가하는 것입니다. 슬프게도 작동하지 않았습니다. 나는 워커에 포함시키지 않았지만 위에서 언급 한 것과 같은 이유로 작동하지 않을 것이라고 생각합니다. 주로 wp_nav_menu"제외"인자가 없지만 잘못 될 수 있습니다.
Marventus

명확성을 위해 원래 게시물을 업데이트했습니다.
Marventus

사용자 정의 워커를 사용 해달라고하면 무엇을, 대신 당신은 정기적으로 nav_menu를 사용하여 사용자 정의 이미지로 wp_get_nav_menu_items와 항목을 () 추출
SAQ

이는 일반적으로 좋은 해결 방법이지만,이 경우 wp_get_nav_menu_itemsimg 태그가 실제 사용자 정의 메뉴에 저장되지 않기 때문에 이미지를 검색하지 않습니다 (파일 이름 만 설명 필드에 있습니다 (예 : "image1.png"). ). 사용자 정의 워커는 메뉴 출력에 img 태그를 삽입 할 수있게 해줍니다.
Marventus
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.