wp_nav_menu ()를 사용하여 메뉴 트리의 일부 / 분기 표시


109

WP Admin에 다음과 같은 메뉴가 정의되어 있습니다.

대체 텍스트

부모 페이지에있을 때마다 사이드 바에 모든 자식 링크를 표시 할 수 있기를 원합니다. 예를 들어, 사용자가 "회사 정보"페이지에있는 경우 녹색으로 강조 표시된 4 개의 링크 목록이 사이드 바에 표시되기를 원합니다.

wp_nav_menu () 에 대한 설명서를 보았고 링크를 생성 할 때 시작점으로 사용할 특정 메뉴의 특정 노드를 지정하는 기본 제공 방법이없는 것으로 보입니다.

페이지 부모가 만든 관계에 의존 하는 비슷한 상황에 대한 솔루션을 만들었지 만 메뉴 시스템을 구체적으로 사용하는 관계를 찾고 있습니다. 도움을 주시면 감사하겠습니다.


2
따라서 전체 메뉴를 사용자 정의 메뉴로 유지하고 싶지만 활성 하위 트리 만 확장하여 표시하는 사용자 정의 워커를 작성 하시겠습니까? 마찬가지로 이 코드 대신 wp_list_pages의 wp_nav_menu 확장? 나는 최근에 비슷한 것을하고 당신이 찾고있는 경우 코드를 게시 할 수 있습니다 ...
goldenapples

1
@goldenapples, 그것이 바로 내가 추구하는 것입니다. 답변으로 코드를 게시하는 것이 마음에 들지 않으면 매우 감사하겠습니다.
jessegavin

1
그러한 명백한 유용한 기능이 이미 구축되어 있지 않은지 궁금합니다. 이는 "CMS"를 수행하는 모든 사이트에 전반적으로 매우 유용합니다.
hakre

위의 문제 또는 비슷한 것을 해결하려고합니다. 대안으로 나는 여기에 CSS 솔루션을
생각해 냈다

답변:


75

이것은 여전히 ​​내 마음에 있었으므로 다시 방문 하여이 솔루션을 구성했습니다.이 솔루션은 컨텍스트에 크게 의존하지 않습니다.

add_filter( 'wp_nav_menu_objects', 'submenu_limit', 10, 2 );

function submenu_limit( $items, $args ) {

    if ( empty( $args->submenu ) ) {
        return $items;
    }

    $ids       = wp_filter_object_list( $items, array( 'title' => $args->submenu ), 'and', 'ID' );
    $parent_id = array_pop( $ids );
    $children  = submenu_get_children_ids( $parent_id, $items );

    foreach ( $items as $key => $item ) {

        if ( ! in_array( $item->ID, $children ) ) {
            unset( $items[$key] );
        }
    }

    return $items;
}

function submenu_get_children_ids( $id, $items ) {

    $ids = wp_filter_object_list( $items, array( 'menu_item_parent' => $id ), 'and', 'ID' );

    foreach ( $ids as $id ) {

        $ids = array_merge( $ids, submenu_get_children_ids( $id, $items ) );
    }

    return $ids;
}

용법

$args = array(
    'theme_location' => 'slug-of-the-menu', // the one used on register_nav_menus
    'submenu' => 'About Us', // could be used __() for translations
);

wp_nav_menu( $args );

사랑스러운 기술! 이것에 관해 뭔가 물어봐도 될까요? 템플릿에 나열된 하위 메뉴 페이지의 내용을 어떻게 표시 하시겠습니까?
daniel.tosaba 5

2
@ daniel.tosaba 당신은 클래스에서 서브 클래스를 작성하거나 필터를 사용해야합니다 Walker_Nav_Menu. 모든 메뉴와 마찬가지로 의견이 너무 많습니다. 새로운 질문을 하시겠습니까?
Rarst


3
환상적인 답변입니다. 정말 고맙습니다. 이것은 실제로 WordPress의 기본 옵션이어야합니다.
dotty

3
정말 깔끔합니다. 관심이 있으신 분은 동일하지만 페이지 ID로 wp_filter_object_list행을 변경하십시오.wp_filter_object_list( $items, array( 'object_id' => $args->submenu ), 'and', 'ID' );
Ben

14

@goldenapples : 워커 클래스 가 작동하지 않습니다. 그러나 아이디어는 정말 좋습니다. 나는 당신의 아이디어를 기반으로 워커를 만들었습니다.

class Selective_Walker extends Walker_Nav_Menu
{
    function walk( $elements, $max_depth) {

        $args = array_slice(func_get_args(), 2);
        $output = '';

        if ($max_depth < -1) //invalid parameter
            return $output;

        if (empty($elements)) //nothing to walk
            return $output;

        $id_field = $this->db_fields['id'];
        $parent_field = $this->db_fields['parent'];

        // flat display
        if ( -1 == $max_depth ) {
            $empty_array = array();
            foreach ( $elements as $e )
                $this->display_element( $e, $empty_array, 1, 0, $args, $output );
            return $output;
        }

        /*
         * need to display in hierarchical order
         * separate elements into two buckets: top level and children elements
         * children_elements is two dimensional array, eg.
         * children_elements[10][] contains all sub-elements whose parent is 10.
         */
        $top_level_elements = array();
        $children_elements  = array();
        foreach ( $elements as $e) {
            if ( 0 == $e->$parent_field )
                $top_level_elements[] = $e;
            else
                $children_elements[ $e->$parent_field ][] = $e;
        }

        /*
         * when none of the elements is top level
         * assume the first one must be root of the sub elements
         */
        if ( empty($top_level_elements) ) {

            $first = array_slice( $elements, 0, 1 );
            $root = $first[0];

            $top_level_elements = array();
            $children_elements  = array();
            foreach ( $elements as $e) {
                if ( $root->$parent_field == $e->$parent_field )
                    $top_level_elements[] = $e;
                else
                    $children_elements[ $e->$parent_field ][] = $e;
            }
        }

        $current_element_markers = array( 'current-menu-item', 'current-menu-parent', 'current-menu-ancestor' );  //added by continent7
        foreach ( $top_level_elements as $e ){  //changed by continent7
            // descend only on current tree
            $descend_test = array_intersect( $current_element_markers, $e->classes );
            if ( !empty( $descend_test ) ) 
                $this->display_element( $e, $children_elements, 2, 0, $args, $output );
        }

        /*
         * if we are displaying all levels, and remaining children_elements is not empty,
         * then we got orphans, which should be displayed regardless
         */
         /* removed by continent7
        if ( ( $max_depth == 0 ) && count( $children_elements ) > 0 ) {
            $empty_array = array();
            foreach ( $children_elements as $orphans )
                foreach( $orphans as $op )
                    $this->display_element( $op, $empty_array, 1, 0, $args, $output );
         }
        */
         return $output;
    }
}

이제 다음을 사용할 수 있습니다.

<?php wp_nav_menu( 
   array(
       'theme_location'=>'test', 
       'walker'=>new Selective_Walker() ) 
   ); ?>

출력은 현재 루트 요소를 포함하는 목록이며 자식이 아닌 자식입니다. 데프 : 루트 요소 : = 현재 페이지에 해당하거나 현재 페이지의 부모 또는 부모의 부모 인 최상위 메뉴 항목 ...

이것은 여전히 ​​원래 질문에 대답하지는 않지만 여전히 최상위 항목이 있으므로 거의 대답하지 않습니다. 사이드 바의 헤드 라인으로 최상위 요소를 원하기 때문에 이것은 나에게 좋습니다. 이를 제거하려면 display_element를 대체하거나 HTML 파서를 사용해야 할 수도 있습니다.


12

안녕하세요 @jessegavin :

탐색 메뉴는 사용자 지정 게시물 유형과 사용자 지정 분류 체계의 조합으로 저장됩니다. 각 메뉴는 (즉 용어로 저장 "메뉴 정보" 에서 발견, wp_terms사용자 정의 분류의) (즉 nav_menu,에서 발견 wp_term_taxonomy.)

각각의 탐색 메뉴 항목은의 게시물로 저장됩니다 post_type=='nav_menu_item'(예 : "는 기업 정보" 에서 발견, wp_posts그것)의 (포스트 메타로 저장 속성을 wp_postmeta사용하여 A) meta_key의 접두사 _menu_item_*경우 _menu_item_menu_item_parent메뉴 항목의 부모 탐색 메뉴 항목 게시물의 ID입니다.

메뉴, 메뉴 아이템의 관계에 저장된 wp_term_relationships위치를 object_id받는 관한 $post->ID순자산의 메뉴 항목은 상기 $term_relationships->term_taxonomy_id에 정의 된 집합 적 메뉴에 관한 wp_term_taxonomywp_terms.

나는 그것을 할 수있을 것이라고 확신 후크 모두 'wp_update_nav_menu''wp_update_nav_menu_item'실제 메뉴 생성 wp_terms과의 관계의 병렬 세트 wp_term_taxonomywp_term_relationships도 하위 탐색 메뉴 항목이가 자신의 탐색 메뉴의되고 모든 탐색 메뉴 항목.

또한 생성 된 Nav 메뉴가 관리자의 사용자 조작을 위해 표시되지 않도록하기 위해 ( 몇 달 전에 수행했던 유사한 작업을 기반으로 WP 3.0에 추가하도록 제안 했습니다) 연결 하고 싶습니다. 정말 빠르게 동기화되지 않으면 데이터 악몽이 생길 것입니다.'wp_get_nav_menus'

재미 있고 유용한 프로젝트 같은데,하지만 내가 데이터를 동기화 아무것도가 모든 버그를 다림질에 관해서 피타 경향이 있기 때문에 부분적으로 지금 해결하기 위해 감당할 수있는 것보다 조금 더 많은 코드 및 테스트입니다 (때문에 지불 클라이언트는 일을 끝내기 위해 나를 압박하고 있습니다. :) 그러나 위의 정보로 무장 한 나는 동기 부여 WordPress 플러그인 개발자가 원하는 경우 코드를 작성할 수 있습니다.

물론 코드를 작성하면 여기에 다시 게시해야하므로 우리 모두가 혜택을 누릴 수 있습니다. :-)


나는 당신이 말하는 것을 따르고 있는지 확실하지 않습니다. 사용자가있는 현재 페이지와 관련된 "하위 메뉴"를 표시하는 읽기 전용 솔루션을 찾고 있습니다. 우리는 같은 것에 대해 이야기하고 있습니까? -데이터베이스 스키마에 대한 자세한 설명에 감사드립니다.
jessegavin

@jessegavin- 예, 전화 하려면 메뉴 구조에 밀접하게 연결되어 있으므로 메뉴wp_nav_menu() 를 복제해야 wp_nav_menu()합니다 . 다른 옵션은 wp_nav_menu()코드 를 복사하고 하위 메뉴로 표시하는 데 필요한 수정을 수행하는 것입니다.
MikeSchinkel

10

이것은 당신이 찾고있는 것을 해야하는 워커 확장입니다.

class Selective_Walker extends Walker_Nav_Menu
{

    function walk( $elements, $max_depth) {

        $args = array_slice(func_get_args(), 2);
        $output = '';

        if ($max_depth < -1) //invalid parameter
            return $output;

        if (empty($elements)) //nothing to walk
            return $output;

        $id_field = $this->db_fields['id'];
        $parent_field = $this->db_fields['parent'];

        // flat display
        if ( -1 == $max_depth ) {
            $empty_array = array();
            foreach ( $elements as $e )
                $this->display_element( $e, $empty_array, 1, 0, $args, $output );
            return $output;
        }

        /*
         * need to display in hierarchical order
         * separate elements into two buckets: top level and children elements
         * children_elements is two dimensional array, eg.
         * children_elements[10][] contains all sub-elements whose parent is 10.
         */
        $top_level_elements = array();
        $children_elements  = array();
        foreach ( $elements as $e) {
            if ( 0 == $e->$parent_field )
                $top_level_elements[] = $e;
            else
                $children_elements[ $e->$parent_field ][] = $e;
        }

        /*
         * when none of the elements is top level
         * assume the first one must be root of the sub elements
         */
        if ( empty($top_level_elements) ) {

            $first = array_slice( $elements, 0, 1 );
            $root = $first[0];

            $top_level_elements = array();
            $children_elements  = array();
            foreach ( $elements as $e) {
                if ( $root->$parent_field == $e->$parent_field )
                    $top_level_elements[] = $e;
                else
                    $children_elements[ $e->$parent_field ][] = $e;
            }
        }

        $current_element_markers = array( 'current-menu-item', 'current-menu-parent', 'current-menu-ancestor' );

        foreach ( $top_level_elements as $e ) {

            // descend only on current tree
            $descend_test = array_intersect( $current_element_markers, $e->classes );
            if ( empty( $descend_test ) )  unset ( $children_elements );

            $this->display_element( $e, $children_elements, $max_depth, 0, $args, $output );
        }

        /*
         * if we are displaying all levels, and remaining children_elements is not empty,
         * then we got orphans, which should be displayed regardless
         */
        if ( ( $max_depth == 0 ) && count( $children_elements ) > 0 ) {
            $empty_array = array();
            foreach ( $children_elements as $orphans )
                foreach( $orphans as $op )
                    $this->display_element( $op, $empty_array, 1, 0, $args, $output );
         }

         return $output;
    }

}

내가 언급 한 mfields의 코드를 느슨하게 기반으로합니다. 메뉴를 탐색 할 때 현재 요소가 (1) 현재 메뉴 항목인지 또는 (2) 현재 메뉴 항목의 조상인지 확인하고, 조건 중 하나에 해당하는 경우에만 하위 트리를 아래로 확장합니다. . 이것이 효과가 있기를 바랍니다.

이를 사용하려면 메뉴를 호출 할 때 "walker"인수를 추가하십시오.

<?php wp_nav_menu( 
   array(
       'theme_location'=>'test', 
       'walker'=>new Selective_Walker() ) 
   ); ?>

오 .. 난 그냥 당신의 질문을 다시 읽고 처음에 내가 잘못 이해했음을 깨달았습니다. 이 워커는 확장하지 않고 다른 모든 최상위 메뉴 항목을 표시합니다. 이것은 정확히 당신이하고 싶었던 것이 아닙니다. 여전히이 코드는 원하는 방식으로 수정할 수 있습니다. 루프 스루를 살펴보고에 $top_level_elements전화하기 전에 나만의 테스트를 추가하십시오 $this->display_element.
goldenapples

이 클래스가 현재 서브 페이지의 깊이를 표시하도록 할 수 있습니까? 즉, 레벨이 3 개 이상인 경우 현재 (하위) 페이지에 대해 세 번째 및 그 이후의 레벨이 표시됩니까? 현재 A> B 만 표시하고 C는 표시하지 않습니다 (C는 세 번째 (레벨)
Zolomon

@ Zolomon-귀하의 질문을 이해하지 못했습니다. 이렇게하면 'current-menu-item', 'current-menu-parent'또는 'current-menu-ancestor'클래스가있는 메뉴 항목 아래에서 전체 트리가 확장됩니다. 테스트하면 메뉴의 모든 하위 페이지 수준이 표시됩니다. 당신은 무엇을 찾고 있습니까?
goldenapples

테마가 어떻게 든 기본값 0을 재정의하는 경우 depth에 대한 호출에 매개 변수 를 전달하고 싶을 수도 있습니다 wp_nav_menu(모든 수준 표시)?
goldenapples

8

업데이트 : 나는 이것을 플러그인으로 만들었습니다. 여기에서 다운로드하십시오 .


나는 이것을 스스로 해결하고 결국 메뉴 조회 결과에 대한 필터 작성을 끝내야했습니다. 일반적으로 사용할 수 wp_nav_menu있지만 부모 요소의 제목을 기준으로 메뉴의 하위 섹션을 선택합니다. 다음 submenu과 같이 메뉴에 매개 변수를 추가하십시오 .

wp_nav_menu(array(
  'menu' => 'header',
  'submenu' => 'About Us',
));

슬래시를 넣어 여러 수준으로 깊이 들어갈 수도 있습니다.

wp_nav_menu(array(
  'menu' => 'header',
  'submenu' => 'About Us/Board of Directors'
));

또는 배열을 선호하는 경우 :

wp_nav_menu(array(
  'menu' => 'header',
  'submenu' => array('About Us', 'Board of Directors')
));

제목의 슬러그 버전을 사용하므로 대문자와 문장 부호를 용서해야합니다.


id를 통해 하위 메뉴에 접근 할 수 있습니까? 페이지 ID 또는 게시물 ID를 의미합니다.
Digerkam

split ()은 더 이상 사용되지 않습니다. $loc = split( "/", $loc );플러그인으로 대체$loc = preg_split( "~/~", $loc );
Floris

또한 $ submenu를 선택적으로 만들 것을 제안합니다. 따라서 필요할 때 여전히 전체 메뉴를 가져올 수 있습니다. 이것을 필터의 맨 위에 추가하십시오 :`if (! isset ($ args-> submenu)) {return $ items; }`
Floris

8

나는 다음 수업을 함께했다. 현재 페이지의 최상위 탐색 상위를 찾거나 워커 생성자에서 대상 최상위 탐색 ID를 제공 할 수 있습니다.

class Walker_SubNav_Menu extends Walker_Nav_Menu {
    var $target_id = false;

    function __construct($target_id = false) {
        $this->target_id = $target_id;
    }

    function walk($items, $depth) {
        $args = array_slice(func_get_args(), 2);
        $args = $args[0];
        $parent_field = $this->db_fields['parent'];
        $target_id = $this->target_id;
        $filtered_items = array();

        // if the parent is not set, set it based on the post
        if (!$target_id) {
            global $post;
            foreach ($items as $item) {
                if ($item->object_id == $post->ID) {
                    $target_id = $item->ID;
                }
            }
        }

        // if there isn't a parent, do a regular menu
        if (!$target_id) return parent::walk($items, $depth, $args);

        // get the top nav item
        $target_id = $this->top_level_id($items, $target_id);

        // only include items under the parent
        foreach ($items as $item) {
            if (!$item->$parent_field) continue;

            $item_id = $this->top_level_id($items, $item->ID);

            if ($item_id == $target_id) {
                $filtered_items[] = $item;
            }
        }

        return parent::walk($filtered_items, $depth, $args);
    }

    // gets the top level ID for an item ID
    function top_level_id($items, $item_id) {
        $parent_field = $this->db_fields['parent'];

        $parents = array();
        foreach ($items as $item) {
            if ($item->$parent_field) {
                $parents[$item->ID] = $item->$parent_field;
            }
        }

        // find the top level item
        while (array_key_exists($item_id, $parents)) {
            $item_id = $parents[$item_id];
        }

        return $item_id;
    }
}

항법 전화 :

wp_nav_menu(array(
    'theme_location' => 'main_menu',
    'walker' => new Walker_SubNav_Menu(22), // with ID
));

4

@ davidn @hakre 안녕하세요, HTML 파서가 없거나 display_element를 재정의하지 않는 못생긴 솔루션이 있습니다.

 class Selective_Walker extends Walker_Nav_Menu
    {
        function walk( $elements, $max_depth) {

            $args = array_slice(func_get_args(), 2);
            $output = '';

            if ($max_depth < -1) //invalid parameter
                return $output;

            if (empty($elements)) //nothing to walk
                return $output;

            $id_field = $this->db_fields['id'];
            $parent_field = $this->db_fields['parent'];

            // flat display
            if ( -1 == $max_depth ) {
                $empty_array = array();
                foreach ( $elements as $e )
                    $this->display_element( $e, $empty_array, 1, 0, $args, $output );
                return $output;
            }

            /*
             * need to display in hierarchical order
             * separate elements into two buckets: top level and children elements
             * children_elements is two dimensional array, eg.
             * children_elements[10][] contains all sub-elements whose parent is 10.
             */
            $top_level_elements = array();
            $children_elements  = array();
            foreach ( $elements as $e) {
                if ( 0 == $e->$parent_field )
                    $top_level_elements[] = $e;
                else
                    $children_elements[ $e->$parent_field ][] = $e;
            }

            /*
             * when none of the elements is top level
             * assume the first one must be root of the sub elements
             */
            if ( empty($top_level_elements) ) {

                $first = array_slice( $elements, 0, 1 );
                $root = $first[0];

                $top_level_elements = array();
                $children_elements  = array();
                foreach ( $elements as $e) {
                    if ( $root->$parent_field == $e->$parent_field )
                        $top_level_elements[] = $e;
                    else
                        $children_elements[ $e->$parent_field ][] = $e;
                }
            }

            $current_element_markers = array( 'current-menu-item', 'current-menu-parent', 'current-menu-ancestor' );  //added by continent7
            foreach ( $top_level_elements as $e ){  //changed by continent7
                // descend only on current tree
                $descend_test = array_intersect( $current_element_markers, $e->classes );
                if ( !empty( $descend_test ) ) 
                    $this->display_element( $e, $children_elements, 2, 0, $args, $output );
            }

            /*
             * if we are displaying all levels, and remaining children_elements is not empty,
             * then we got orphans, which should be displayed regardless
             */
             /* removed by continent7
            if ( ( $max_depth == 0 ) && count( $children_elements ) > 0 ) {
                $empty_array = array();
                foreach ( $children_elements as $orphans )
                    foreach( $orphans as $op )
                        $this->display_element( $op, $empty_array, 1, 0, $args, $output );
             }
            */

/*added by alpguneysel  */
                $pos = strpos($output, '<a');
            $pos2 = strpos($output, 'a>');
            $topper= substr($output, 0, $pos).substr($output, $pos2+2);
            $pos3 = strpos($topper, '>');
            $lasst=substr($topper, $pos3+1);
            $submenu= substr($lasst, 0, -6);

        return $submenu;
        }
    }

그들 모두를 시도한 후에, Alp의 솔루션은 나를 위해 일한 유일한 솔루션이었습니다. 그러나 한 가지 문제가 있습니다. 첫 번째 수준의 어린이 만 표시하지만 세 번째 또는 네 번째 수준의 어린이는 표시하지 않습니다. 나는 그것을하기 위해 며칠 동안 노력해 왔습니다. 솔루션을 수정하는 방법을 아는 사람이 있습니까? 추신. 주석을 추가 할 수 없으므로 답변으로해야합니다.
cchiera

3

탐색 메뉴 출력에는 현재 항목, 현재 항목 조상에 대한 많은 클래스가 포함되어 있습니다. 일부 상황에서는 전체 탐색 트리 출력을 허용 한 다음 CSS를 사용하여 현재 페이지의 하위 만


3

도움이 될 수정 워커를 만들었습니다! 완벽하지는 않습니다-몇 가지 빈 요소가 남지만 트릭을 수행합니다. 수정은 기본적으로 $ current_branch 비트입니다. 그것이 누군가를 돕기를 바랍니다!

class Kanec_Walker_Nav_Menu extends Walker {
/**
 * @see Walker::$tree_type
 * @since 3.0.0
 * @var string
 */
var $tree_type = array( 'post_type', 'taxonomy', 'custom' );

/**
 * @see Walker::$db_fields
 * @since 3.0.0
 * @todo Decouple this.
 * @var array
 */
var $db_fields = array( 'parent' => 'menu_item_parent', 'id' => 'db_id' );

/**
 * @see Walker::start_lvl()
 * @since 3.0.0
 *
 * @param string $output Passed by reference. Used to append additional content.
 * @param int $depth Depth of page. Used for padding.
 */
function start_lvl(&$output, $depth) {
    $indent = str_repeat("\t", $depth);
    $output .= "\n$indent<ul class=\"sub-menu\">\n";
}

/**
 * @see Walker::end_lvl()
 * @since 3.0.0
 *
 * @param string $output Passed by reference. Used to append additional content.
 * @param int $depth Depth of page. Used for padding.
 */
function end_lvl(&$output, $depth) {
    global $current_branch;
    if ($depth == 0) $current_branch = false;
    $indent = str_repeat("\t", $depth);
    $output .= "$indent</ul>\n";
}

/**
 * @see Walker::start_el()
 * @since 3.0.0
 *
 * @param string $output Passed by reference. Used to append additional content.
 * @param object $item Menu item data object.
 * @param int $depth Depth of menu item. Used for padding.
 * @param int $current_page Menu item ID.
 * @param object $args
 */
function start_el(&$output, $item, $depth, $args) {
    global $wp_query;
    global $current_branch;

    // Is this menu item in the current branch?
    if(in_array('current-menu-ancestor',$item->classes) ||
    in_array('current-menu-parent',$item->classes) ||
    in_array('current-menu-item',$item->classes)) {
        $current_branch = true; 
    }

    if($current_branch && $depth > 0) {
        $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 ) );
        $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        ) .'"' : '';

        $item_output = $args->before;
        $item_output .= '<a'. $attributes .'>';
        $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
        $item_output .= '</a>';
        $item_output .= $args->after;

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

}

/**
 * @see Walker::end_el()
 * @since 3.0.0
 *
 * @param string $output Passed by reference. Used to append additional content.
 * @param object $item Page data object. Not used.
 * @param int $depth Depth of page. Not Used.
 */
function end_el(&$output, $item, $depth) {
    global $current_branch;
    if($current_branch && $depth > 0) $output .= "</li>\n";
    if($depth == 0) $current_branch = 0;
}

}


3

내 플러그인에서 코드를 확인하거나 목적에 맞게 사용하십시오.)

이 플러그인은 향상된 "탐색 메뉴"위젯을 추가합니다. 위젯을 통해 사용자 정의 메뉴의 출력을 사용자 정의하도록 설정할 수있는 많은 옵션을 제공합니다.

특징은 다음과 같습니다.

  • 사용자 정의 계층 구조- "관련된 하위 항목 만"또는 "엄격히 관련된 하위 항목 만"
  • 시작 깊이 및 최대 표시 레벨 + 평면 디스플레이.
  • 선택한 항목으로 시작하는 모든 메뉴 항목을 표시합니다.
  • 현재 요소에 대한 직접 경로 만 표시하거나
    선택한 항목의 하위 항목 만 표시합니다 (부모 항목을 포함하는 옵션).
  • 위젯 블록의 사용자 정의 클래스.
  • 그리고 wp_nav_menu 함수에 대한 거의 모든 매개 변수.

http://wordpress.org/extend/plugins/advanced-menu-widget/

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