メニュー
カスタムメニュー を登録する
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の表示/非表示
}
});