メニュー

カスタムメニュー を登録する

functions.phpに下記コードを記述

このコードを記述すると外観からメニューをカスタムできる。

    
//*******************************************************************
//  外観にメニューを追加(pc、sp用のheaderカスタムメニュー)
//*******************************************************************
function register_menu()
{
    register_nav_menu('header-pc', 'ヘッダー(PC)');
    register_nav_menu('header-sp', 'ヘッダー(SP)');
}
add_action('after_setup_theme', 'register_menu');
    

footerにもメニューを設置したい場合はコードを追加する。

    
//例
register_nav_menu('footer-pc', 'フッター(PC)');
    

必要な項目を追加する

外観 > メニュー からメニューに追加したいページを追加していく。

クラス名はまだつけなくて平気。(<li>タグにクラス名をつけるコードをfunctions.phpに記述するため)

<li>タグにクラス名をつける

functions.phpに下記コードを記述

    
//************************************************************************
//  liのクラス名を変更
//************************************************************************
function add_custom_classes_based_on_menu($classes, $item, $args, $depth) {
    // メニューの位置(theme_location)に応じてクラスを追加
    if ($args->theme_location === 'header-pc') {
        $classes[] = 'headerNav__item--pc';
    } elseif ($args->theme_location === 'header-sp') {
        $classes[] = 'headerNav__item--sp';
    }

    // 外観 > メニューで設定されたクラスを保持
    $classes = array_merge($classes, (array) $item->classes);

    // デフォルトのクラスを削除(menu-itemなど)
    $classes = array_diff($classes, ['menu-item', 'menu-item-type-custom', 'menu-item-object-custom', 'menu-item-has-children', 'menu-item-type-post_type', 'menu-item-object-page']); 

    return $classes;
}
add_filter('nav_menu_css_class', 'add_custom_classes_based_on_menu', 10, 4);
    

登録したメニューを呼び出す

下記コードをheader.phpの<head>の中に記述する

    
<nav class="headerNav-pc">
  <ul class="headerNav__list--pc">
    <?php
    wp_nav_menu(array(
      'theme_location' => 'header-pc', // functions.phpに登録したメニューの名前
      'container' => false, // 自動で囲う 'div'タグを無効にする
      'items_wrap' => '%3$s', // <ul>タグを手動で指定するので無効にする
      'fallback_cb' => '"', // メニューが未設定の場合は何も表示しない
    ));
    ?>
  </ul>
</nav>

    

※これはpc用なのでspやフッターのコードも必要に応じて追加する。(フッターの場合は<footer>の中に記述。)

ここまでで正常に表示されているはず

サブメニューが必要な場合

項目を追加

カスタムメニューの設定で追加。

各コードを追加

PHPから書いた方がわかりやすい

PHP

カスタムウォーカーでクラス名などを追加(php)

下記コードをfunctions.phpに記述

メニュー名header-pc、header-sp共通

・外観>メニューで追加するクラス名も反映

・不要なクラス名、idは削除

・サブメニューがある親の<li>にacoItemというクラス名を追加

・サブメニューの<ul>のクラス名をsubMenu

・サブメニューの<li>のクラス名をsubMenu__item

メニュー名header-pcの時

・<li>のクラス名をheaderNav__item–pc

メニュー名header-spの時

・<li>のクラス名をheaderNav__item–sp

・サブメニューがある親の<a>のhrefは削除

    
//****************************************************************************************
// liのクラス名を変更
//****************************************************************************************
class Custom_Walker_Nav_Menu extends Walker_Nav_Menu
{
    // メニューの<li>をカスタマイズ
    public function start_el(&$output, $item, $depth = 0, $args = null, $id = 0)
    {
        // クラス名の初期化
        $classes = [];
        $item_classes = empty($item->classes) ? [] : (array) $item->classes;

        // メニュー名(header-pc, header-sp)に応じてクラスを追加
        if ($args->theme_location === 'header-pc') {
            $classes[] = 'headerNav__item--pc';
        } elseif ($args->theme_location === 'header-sp') {
            $classes[] = 'headerNav__item--sp';
        }

        // サブメニューがある親に特定のクラスを追加
        if ($depth === 0 && in_array('menu-item-has-children', $item_classes, true)) {
            $classes[] = 'acoItem';
        }

        // サブメニュー用のクラス
        if ($depth > 0) {
            $classes[] = 'subMenu__item';
        }

        // 外観 > メニューで追加されたクラスを保持
        $classes = array_merge($classes, $item_classes);

        // 不要なクラスを削除
        $unwanted_classes = [
            'menu-item', 
            'menu-item-type-custom', 
            'menu-item-object-custom', 
            'menu-item-has-children', 
            'menu-item-type-post_type', 
            'menu-item-object-page', 
            'menu-item-home', 
            'current-menu-ancestor'
        ];
        $classes = array_diff($classes, $unwanted_classes);

        // クラス名をHTML形式に変換
        $class_names = join(' ', array_filter($classes));
        $class_names = $class_names ? ' class="' . esc_attr($class_names) . '"' : '';

        // サブメニューの親の場合、リンクを無効化する
        $link = $item->url && !($args->theme_location === 'header-sp' && $depth === 0 && in_array('menu-item-has-children', $item_classes, true))
            ? ' href="' . esc_url($item->url) . '"'
            : '';

        // メニューアイテムのHTMLを出力
        $output .= sprintf(
            '<li%1$s><a%2$s>%3$s</a>',
            $class_names,
            $link,
            esc_html($item->title)
        );
    }

    // サブメニューの<ul>をカスタマイズ
    public function start_lvl(&$output, $depth = 0, $args = null)
    {
        $classes = ['subMenu']; // サブメニュー用のクラス名
        $class_names = ' class="' . esc_attr(join(' ', $classes)) . '"';
        $output .= '<ul' . $class_names . '>';
    }
}

// カスタムウォーカーをメニューに適用する
function apply_custom_walker($args)
{
    if (isset($args['theme_location']) && in_array($args['theme_location'], ['header-pc', 'header-sp'])) {
        $args['walker'] = new Custom_Walker_Nav_Menu();
    }
    return $args;
}
add_filter('wp_nav_menu_args', 'apply_custom_walker');    

CSS

サブメニューのスタイル変更

下記コードをstyle.cssに記述

    
/*******************************************
headerサブメニュー
*******************************************/
.current_page_parent {
    background-color: var(--gray);
}

.acoItem {
    position: relative;

    & a {
        cursor: pointer;
    }

    & .subMenu {
        width: 100%;
        position: absolute;
        left: 50%;
        top: 100%;
        transform: translateX(-50%);
        background-color: #f2f2f2;
        opacity: 0;
        visibility: hidden;
        transition: var(--transitionBase);

        & a {
            width: 100%;
            text-align: center;
        }
    }

    &:hover .subMenu {
        opacity: 1;
        visibility: visible;
    }
}

@media screen and (max-width:1024px) {
    .acoItem {

        &>a::before,
        &>a::after {
            position: absolute;
            content: "";
            width: 10px;
            height: 1px;
            background-color: var(--black);
            top: 50%;
            left: 103%;
            transition: var(--transitionBase);

        }

        &>a::before {
            transform: translateY(-50%);
        }

        &>a::after {
            transform: translateY(-50%) rotate(90deg);
        }

        & .subMenu {
            display: none;
            opacity: 1;
            visibility: visible;
            transition: none;
        }

        &.open>a::before {
            transform: translateY(-50%) rotate(180deg);
        }

        &.open>a::after {
            transform: translateY(-50%) rotate(360deg);
        }

    }
}
    

JavaScript

SP 時サブメニュー開閉

下記コードをscript.jsに記述

    
  /*******************************************
   sp時サブメニュー開閉
  *******************************************/
  $(document).on('click', '.acoItem', function () {
    if ($(window).width() <= 1024) {
      $(this).toggleClass('open');  // openクラスをトグル

      // .acoItemに関連する.subMenuを開閉
      $(this).find('.subMenu').slideToggle(); // subMenuの表示/非表示
    }
  });