web-dev-qa-db-ja.com

Simple Navigation Walker - 最初のサブメニューを囲むラッパークラス

ナビゲーションの最初のサブメニューを別々のdivにラップしようとしています。子供やサブレベルのどれも同じ治療を受けるべきではありません。

私はNav Walkerのことは本当に初めてです、そして私は本当に苦労していてそしていくらかの助けを必要とするかもしれません?

これが私が達成しようとしている構造です。

<ul class="menu">
    <li class="menu-item">
        <a href="#">Menu Item</a>
        <!-- wrapper-class around the first sub-menu -->
        <div class="sub-menu__wrapper">
            <ul class="sub-menu">
                <li class="menu-item">
                    <a href="#">Menu Item</a>
                    <!-- NO wrapper-class around following levels -->
                    <ul class="sub-menu">
                        <li>...</li>
                    </ul>
                </li>
            </ul>
        </div>
    </li>
</ul>

最初のレベルにsub-menu__wrapperを表示するだけの単純なif文を使用するのは簡単だと思いましたが、どういうわけか次のHTML出力は混乱してしまいます。

これが私のWalkerクラスです。

class sublevel_wrapper extends Walker_Nav_Menu {
    function start_lvl( &$output, $depth = 0, $args = array() ) {
        if ($depth == 0) {
            $output .= "<div class='sub-menu__wrapper'><ul class='sub-menu'>\n";
        }
        //$output .= "<ul class='sub-menu'>\n";
    }
    function end_lvl( &$output, $depth = 0, $args = array() ) {
        if ($depth == 0) {
            $output .= "</ul></div>\n";
        }
        //$output .= "</ul>\n";
    }
}

これは以下の構造を出力します。

<ul class="menu">
    <li class="menu-item">
        <a href="#">Menu Item</a>
        <!-- wrapper-class around the first sub-menu -->
        <div class="sub-menu__wrapper">
            <ul class="sub-menu">
                <li class="menu-item">Parent Menu Item</li>
                <!-- the following items are supposed to be nested in the "parent menu item" before -->
                <li class="menu-item">Child Menu Item</li>
                <li class="menu-item">Child Menu Item</li>
                <li class="menu-item">Child Menu Item</li>
                <li class="menu-item">Parent Menu Item</li>
                <!-- again the following items are supposed to be nested in the "parent menu item" before -->
                <li class="menu-item">Child Menu Item</li>
                <li class="menu-item">Child Menu Item</li>
                <li class="menu-item">Child Menu Item</li>
                ...
            </ul>
        </div>
    </li>
</ul>

あなたがコメントで見ることができるように、ifステートメントが偽であるならば、私は出力を変更しようとしました、しかしそれはさらにもっと出力をめちゃくちゃにします?

正しい方向への任意の助け、建設的な批判やナッジは大歓迎です????

1
Jörg Mayer

正直に言うと、私のソリューションがなぜうまくいくのか本当にわかりませんが、それは可能ですか。

私はこのソリューションをスニペットに基づいて作成し、自分のニーズに合わせて出力を調整しました。 深さに応じて出力が異なるカスタムナビゲーションウォーカー

class sublevel_wrapper extends Walker_Nav_Menu {
    // add classes to ul sub-menus
    function start_lvl( &$output, $depth = 0, $args = array() ) {
        // depth dependent classes
        $indent = ( $depth > 0  ? str_repeat( "\t", $depth ) : '' ); // code indent
        $display_depth = ( $depth + 1); // because it counts the first submenu as 0
        $classes = array(
            'sub-menu',
            'menu-depth-' . $display_depth
        );
        $class_names = implode( ' ', $classes );

        // build html
        if ($display_depth == 1) {
            $output .= "\n" . $indent . '<div class="sub-menu__wrapper"><ul class="' . $class_names . '">' . "\n";
        } else {
            $output .= "\n" . $indent . '<ul class="' . $class_names . '">' . "\n";
        }
    }
}

私の最初のスニペットと比較して、彼はend_lvl関数を完全に除外し、それがどんな理由でもうまくいった。私は彼が$ display_depth変数を追加する方法も好きでした。

1
Jörg Mayer
function sevenMenu(  ) {
$menu_name = 'primary'; // specify custom menu slug
$menu_list ='';
if (($locations = get_nav_menu_locations()) && isset($locations[$menu_name])) {
    $menu = wp_get_nav_menu_object($locations[$menu_name]);
    $menu_items = wp_get_nav_menu_items($menu->term_id);

    foreach( $menu_items as $menu_item ) {
        if( $menu_item->menu_item_parent == 0 ) {

            $parent = $menu_item->ID;

            $menu_array = array();
            foreach( $menu_items as $submenu ) {
                if( $submenu->menu_item_parent == $parent ) {
                    $bool = true;
                    $menu_array[] = '<li><a href="' . $submenu->url . '">' . $submenu->title . '</a></li> ' ."\n";
                }
            }
            if( $bool == true && count( $menu_array ) > 0 ) {
                $menu_list .= '<li role="presentation" class="dropdown">' ."\n";
                $menu_list .= '<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">' . $menu_item->title . ' <span class="caret"></span></a>' ."\n";

                $menu_list .= '<ul class="dropdown-menu">' ."\n";
                $menu_list .= implode( "\n", $menu_array );
                $menu_list .= '</ul>' ."\n";

            } else {

                $menu_list .= '<li>' ."\n";
                $menu_list .= '<a href="' . $menu_item->url . '">' . $menu_item->title . '</a>' ."\n";
                $menu_list .= '<li>' ."\n";
            }

        }

        // end <li>

    }

} else {
    $menu_list = '<!-- no menu defined in location "'.$theme_location.'" -->';
}

echo $menu_list;}

このブートストラップメニューをチェックアウトするには、あなたのfunction.phpにこれを追加します。

<?php if (function_exists(sevenMenu())) sevenMenu(); ?>
1
Roland Allla