Walker_Nav_Menu를 수정할 때 부모 li에 'has_children'클래스 추가


22

wp_nav_menu에 대한 사용자 정의 워커 클래스를 작성 중이며 li에 하위 메뉴가 있는지 여부를 지정할 수 있기를 원합니다. 그래서 마크 업을 원합니다 :

<li class="has_children [other-wordpress-classes]">
    <a class="parent-link">Some item</a>
    <ul class="sub-menu">

클래스를 추가하고 제거하는 방법을 알고 있습니다. 현재 항목에 하위 항목이 있는지 알려주는 내용이 없습니다.

어떤 아이디어?

미리 감사드립니다.

답변:


23

start_el()이 정보를 $args매개 변수로 가져와야$args 하지만 WordPress 는 배열경우에만 정보를 채우는 반면 사용자 정의 탐색 메뉴의 경우 객체입니다. 이것은 Trac 티켓에 보고됩니다 . 그러나 display_element()사용자 지정 워커 의 메서드를 재정의 하면 자식 요소 배열에 액세스 할 수있는 가장 쉬운 위치이기 때문에 문제없이 직접 채울 수 있습니다 .

class WPSE16818_Walker extends Walker_Nav_Menu
{
    function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output )
    {
        $id_field = $this->db_fields['id'];
        if ( is_object( $args[0] ) ) {
            $args[0]->has_children = ! empty( $children_elements[$element->$id_field] );
        }
        return parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
    }

    function start_el( &$output, $item, $depth, $args ) {
        if ( $args->has_children ) {
            // ...
        }
    }

Jan Jan, 이 질문에 도움 될 수 있습니까 ? 코드를 시도했지만 작동시키지 못했습니다. 샘플 코드 좀 더 주 시겠어요?
Giri

이 페이지 의 전체 구현 예를 자세히 참조하십시오.
rjb

감사합니다 @Jan fabry .. 나는 나의 맞춤식 워커를 견뎌냈습니다.
Harish Chinju

7

업데이트 : 현재로 워드 프레스 3.7 - 그것은 워드 프레스 코어에 알아서 것 같은 사용자 정의 워커를 사용할 필요를 (년 10 월 2013), CSS 클래스는 테마 메뉴에 하위 메뉴 항목 및 페이지를 나타 내기 위해 추가되었습니다.

CSS 클래스의 이름은 menu-item-has-childrenpage_item_has_children입니다.


서두르는 사람을위한 완벽한 솔루션 (Jan Fabry의 이전 답변에 대한 크레딧)은 아래의 전체 구현을 참조하십시오.

테마의 템플리트에서 탐색을 출력하십시오.

wp_nav_menu( array(
    'theme_location' => 'navigation-primary',
    'container' => false,
    'container_class' => '',
    'container_id' => '',
    'menu_class' => '',
    'menu_id' => '',
    'walker' => new Selective_Walker(),
    'depth' => 2
    )
);

그런 다음 테마에 다음을 포함하십시오 functions.php.

class Selective_Walker extends Walker_Nav_Menu {
    function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ) {
        $id_field = $this->db_fields['id'];

        if ( is_object( $args[0] ) ) {
            $args[0]->has_children = !empty( $children_elements[$element->$id_field] );
        }

        return parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
    }

    function start_el( &$output, $item, $depth, $args ) {
        if ( $args->has_children ) {
            $item->classes[] = 'has_children';
        }

        parent::start_el(&$output, $item, $depth, $args);
    }
}

결과 HTML 출력은 다음과 유사합니다.

<ul>
    <li><a href="#">Home</a></li>
    <li class="has_children"><a href="#">About</a>
        <ul class="sub-menu">
            <li><a href="#">Our Mission</a></li>
        </ul>
    </li>
    <li><a href="#">Services</a></li>
    <li class="has_children"><a href="#">Products</a>
        <ul class="sub-menu">
            <li><a href="#">Lorem Ipsum</a></li>
            <li><a href="#">Lorem Ipsum</a></li>                
        </ul>
    </li>
    <li><a href="#">Contact Us</a></li>
</ul>

WordPress의 워커 클래스 사용에 대한 자세한 내용 은 워커 클래스 이해를 참조하십시오 .

즐겨!


치명적인 오류 : 44 번 라인의 D : \ www \ wordpress \ wp-content \ themes \ wpt_theme \ functions.php에서 콜 타임 통과 기준이 제거되었습니다.
Tahir Yasin

44 번 라인은 parent :: start_el (& $ output, $ item, $ depth, $ args);
Tahir Yasin

2

이 기능은 정확히 원하는 것입니다. 또한 탐색 메뉴 항목을 수정하는 매우 효과적인 방법을 보여줍니다. 또한 항목 필터를 통해보다 고급 (예 : 하위 테마) 기능을 위해 열 수 있습니다.

/**
 * Classes for a navigation named "Topnav" in the nav location "top".
 * Shows examples on how to modify the current nav menu item
 * 
 * @param (object) $items
 * @param (object) $menu
 * @param (object) $args
 */
function wpse16818_nav_menu_items( $items, $menu, $args )
{
    # >>>> start editing

    // examples for possible targets
    $target['name'] = 'Topnav';
    // The targeted menu item/s
    $target['items'] = array( (int) 6 );

    # <<<< stop editing

    // filter for child themes: "config_nav_menu_topnav"
    $target = apply_filters( 'config_nav_menu_'.strtolower( $target['name'] ), $target );

    // Abort if we're not with the named menu
    if ( $menu->name !== $target['name'] ) 
        return;

    foreach ( $items as $item )
    {
        // Check what $item contains
        echo '<pre>'; print_r($item); echo '</pre>';

        // First real world example:
        $item->classes = 'span-4';

        // Second real world example:
        // Append this class if we are in one of the targeted items
        if ( in_array( (int) $item->menu_order, $target['items'] ) )
            $item->classes .= ' last';
    }

    return $items;
}
add_filter( 'wp_get_nav_menu_items', 'wpse16818_nav_menu_items', 10, 3 );

네, 거의 모든 경우에 커스텀 워커가 필요 없습니다.


고마워, 지금은 워커가 필요하지만 다음 번에는 이것에 대해 살펴볼 것입니다!
patnz

1

드롭 다운을 만들고 싶다면 CSS로만 할 수 있습니다. 자식과 함께 WP에서 사용자 지정 탐색을 수행하면 WordPress에서 자동으로 클래스 하위 메뉴를 자식 ul에 할당합니다. 이 CSS를 사용해보십시오

    nav li {position:relative;}
   .sub-menu {display:none; position:absolute; width:300px;}
    nav ul li:hover ul {display:block;}

약간의 향신료를 만들기 위해 jQuery를 추가하고 싶을 수도 있지만 작업 드롭 다운 메뉴가 표시됩니다.


감사합니다. 제어 요소를 삽입하는 다중 수준의 축소 가능한 트리 메뉴이지만 CSS로 가능한 많은 작업을 수행하는 것이 좋습니다!
patnz

-1
if ( $this->has_children ) {
    $item_output .= 'has_children';
}

3
이 코드의 기능과 질문에 어떻게 대답하는지 설명하십시오.
cybmeta

더 많은 맥락에서 코드를 게시하십시오. 마찬가지로, 방문하는 대부분의 사람들은 어디에 붙여 넣기를 시도해야하는지 알지 못합니다.
s_ha_dum
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.