[WordPress]カスタムメニュー機能の設定と設置と書き出されるソースコードを分かりやすく紹介します

WordPressテーマ制作の案件を多く受託することがあるんですが、残念ながら今までしっかりとWordPressに備え付けられているカスタムメニューという機能を活用することを前提に、設計・デザイン・コーディングされた案件に出会ったことがありませんでした。

WordPressを多く扱っている者としては普通と認識していることでも、周りがそうとは限りません。そして、せっかくユーザーにも便利に活用してもらえる機能なだけに、もっと中から外へ情報を発信していかないといけないのではないかと思いました。

今回はその、カスタムメニューの使い方についてまとめてみました。

カスタムメニューとは

カスタムメニューとは、管理画面から簡単に操作でき、任意の投稿や固定ページを任意の場所に表示することができるメニューのことを言います。

固定ページの一覧を表示する関数はすでにありますが、固定ページとカテゴリー、投稿などを混在させたり、順序を自由に決めることができません。カスタムメニューではそれらの不満を解消することができます。

メニューの作り方

まずは【管理画面】→【外観】→【メニュー】と進みます。

未だカスタムメニューを作成したことがない場合には、下のような表示になると思います。ここでは試しに[global]という名前のメニューを作成してみます。メニュー名を入力して【メニューを作成】を押します。

左側から任意のページを選んでみましょう。

チェックをして【メニューに追加】を押すと、

追加されましたね。カスタムメニューは「リンク先URL」と「ラベル」を設定することができます。管理しているWordPress内のページ以外の外部のサイトにリンクを張る場合に利用できます。

下のように、カスタムメニューに登録できる項目は、【投稿】【固定ページ】【カスタムリンク】【カテゴリー】の4項目となります。

メニューの位置については、詳しく後述します。

カスタムメニューを含むWordPressの基本的な使い方を学習したい場合には、こちらの書籍がおすすめです。著者の方々もWordPressコミュニティで活躍されているみなさんです。とてもわかりやすいので、僕はWordPressを触った経験がないお客様には、こちらの書籍をプレゼントしたりします。

では、実際にテーマにカスタムメニューの位置を定義していきましょう。

カスタムメニューの位置をfunctions.phpに定義する

では、functions.phpファイルを開いて、カスタムメニューの位置を設定していきます。

if ( ! function_exists( 'lab_setup' ) ) :

function lab_setup() {

	register_nav_menus( array(
		'global' => 'グローバルナビ',
		'header' => 'ヘッダーナビ',
		'footer' => 'フッターナビ',
	) );

}
endif;
add_action( 'after_setup_theme', 'lab_setup' );

順に説明していきます。

1行目のif文ですが、lab_setup()がない場合にlab_setup()を読み込む、という条件分岐になります。こうしておくことによって、子テーマでlab_setup()を定義した際に上書きすることができます。

2行目からlab_setup()関数を定義していきます。

カスタムメニューの位置を定義するには、register_nav_menus()を使います。今回は複数の位置を定義してみます。1つだけしか定義しない場合にも同じように1つだけ書けば大丈夫です。

参照:関数リファレンス/register nav menus

最後に、after_setup_themeのタイミングでlab_setup()が実行されるようにアクションフックを追加します。

先ほど後述すると書いてあったメニュー位置ですが、こちらが方法になります。次は実際に表示させてみましょう。

カスタムメニューを表示する

カスタムメニューを表示させるためには、wp_nav_menu()を利用し、パラメータで先ほど定義した位置やメニューを囲むタグ、メニューの表示階層数などを指定します。

参照:テンプレートタグ/wp nav menu

<div class="global-navi">
	<?php
		wp_nav_menu( array(
			'theme_location' => 'global',
			'container'      => 'div',
			'depth'          => 1,
		) );
	?>
</div>

1行目:スタイリングしやすいように、div要素にglobal-naviクラスを付けてメニューを囲っています。
3行目:wp_nav_menu()でメニューを表示させます
4行目:theme_locationでどのテーマ位置のテーマを表示するかを指定します
5行目:メニュー自体を囲うタグをdiv要素に指定します
6行目:メニューを何階層表示するかを指定します。1と指定しているので親メニューだけを表示させるよう指定しています(0を指定すると全階層表示)

現状、実際の表示はこのようになります。

何もスタイリングしていないので、まっさらなHTML表示になっています。書き出されているHTMLはこのようになります。

<div class="global-navi">
  <div class="menu-global-container">
    <ul id="menu-global" class="menu">
      <li id="menu-item-2117" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children menu-item-2117"><a href="/sample-page-2/">サンプルページ</a></li>
      <li id="menu-item-2118" class="menu-item menu-item-type-post_type menu-item-object-post menu-item-2118"><a href="/2017/06/01/hello-world/">Hello world!</a></li>
      <li id="menu-item-2119" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-2119"><a href="http://yahoo.co.jp">Yahoo!</a></li>
      <li id="menu-item-2120" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-2120"><a href="/category/%e3%83%9e%e3%83%bc%e3%82%af%e3%82%a2%e3%83%83%e3%83%97/">マークアップ</a></li>
    </ul>
  </div>
</div>

Codexにもありますが、wp_nav_menu()で設定できるパラメータは以下のようになります。テンプレート的に使えますのでご利用ください。

<div class="global-navi">
    <?php wp_nav_menu( array(
        'menu'            => 'hogehoge', //どんな意味があるのかよく分かりません…
        'menu_class'      => 'menu_class', // メニューを構成するul要素につけるCSSクラス名
        'menu_id'         => 'menu_id', // メニュを構成するul要素につけるCSSI ID名
        'container'       => 'div', // ulを囲う要素を指定。div or nav。なしの場合には false
        'container_class' => 'container_class', // コンテナに適用するCSSクラス名
        'container_id'    => 'container_id', // コンテナに適用するCSS ID名
        'fallback_cb'     => 'wp_page_menu', // メニューが存在しない場合にコールバック関数を呼び出す
        'before'          => '[before]', // メニューアイテムのリンクの前に挿入するテキスト
        'after'           => '[after]', // メニューアイテムのリンクの後に挿入するテキスト
        'link_before'     => '[link_before]', // リンク内の前に挿入するテキスト
        'link_after'      => '[link_after]', // リンク内の後に挿入するテキスト
        'echo'            => true, // メニューをHTML出力する(true)かPHPの値で返す(false)か
        'depth'           => 1, // 何階層まで表示するか。0は全階層、1は親メニューまで、2は子メニューまで…という感じ
        'walker'          => '', // カスタムウォーカーを使用する場合
        'theme_location'  => 'global', // メニュー位置を指定
        'items_wrap'      => '<ul id="%1$s" class="%2$s">%3$s</ul>', // メニューアイテムのラップの仕方。%1$sには'menu_id'のパラメータ展開、%2$sには'menu_class'のパラメータ展開、%3$sはリストの項目が値として展開されます
    ) ); ?>
</div>

こちらの書き出されるHTMLコードは以下になります。

<div class="global-navi">
    <div id="container_id" class="container_class">
        <ul id="menu_id" class="menu_class">
            <li id="menu-item-2117" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children menu-item-2117">[before]<a href="/sample-page-2/">[link_before]サンプルページ[link_after]</a>[after]</li>
            <li id="menu-item-2118" class="menu-item menu-item-type-post_type menu-item-object-post menu-item-2118">[before]<a href="/2017/06/01/hello-world/">[link_before]Hello world![link_after]</a>[after]</li>
            <li id="menu-item-2119" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-2119">[before]<a href="http://yahoo.co.jp">[link_before]Yahoo![link_after]</a>[after]</li>
            <li id="menu-item-2120" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-2120">[before]<a href="/category/%e3%83%9e%e3%83%bc%e3%82%af%e3%82%a2%e3%83%83%e3%83%97/">[link_before]マークアップ[link_after]</a>[after]</li>
        </ul>
    </div>
</div>

こちらの書き出されるコードをちょっと理解しておくだけで、デザインが実現可能かどうか判断できると思います。(当然、デザイナーも少しはマークアップできるという前提ですが)

カスタムメニューをデザインする

では、このように書き出されたHTMLをどのようにデザインするのかを簡単に説明します。

先ほど掲載したHTMLソースコードをご覧いただくとわかるかと思うのですが、ほぼ全ての要素に自動的にIDやClassが設置されているので、CSSでのスタイリングにIDやClassに関して困ることはほぼないでしょう。

自動的に付与されるよく使うCSSクラス名

より一層、スタイリングをスマートに行う為にも、この書き出されるIDやClassの規則性を理解しておくことが必要となります。

下の表によく使うclass名と説明を掲載しておきますので参考にしてみてください。

class説明
menu-item全てのメニューに共通して付与されるクラス名
menu-item-object-[pbject]全てのメニュー項目に付与されて、表示されているメニュー項目のタイプによって[object]部分が[page]:固定ページ、[post]:投稿、[custom]:カスタムメニュー、[category]:カテゴリーと変わります
current-menu-item現在表示しているページのメニュー項目に付与される
current-menu-parent現在表示しているページの親ページにあたるメニュー項目に付与される
current-menu-ancestor現在表示しているページの祖先ページにあたる項目に付与される
menu-item-homeトップページの項目に付与される

任意のCSSクラス名を追加する

管理画面から任意のメニュー項目に独自のCSSクラス名を付与することもできます。

まずは【管理画面】から【外観】→【メニュー】に進みます。すると、管理画面右上のあたりに【表示オプション】というタブが【ヘルプ】とならんで見えると思いますのでクリックします。

表示されたタブの中に【CSSクラス】という項目があるはずなので、そちらにチェックを入れます。

先ほど追加したメニューの項目(画面では「サンプルページ」という名前の固定ページ)の右側にある▲マークをクリックして、中身を展開してみましょう。

すると、先ほどまではなかった【CSSクラス(オプション)】という項目が表示されているはずです。こちらに任意のCSSクラス名を入力することによって、自由にメニュー項目にクラス名を追加することができます。

例として画像のように【sample-page】というクラス名を固定ページ:サンプルページに追加した際の、書き出されるHTMLソースコードを確認してみましょう。

<div class="global-navi">
    <div class="menu-global-container">
        <ul id="menu-global" class="menu">
            <li id="menu-item-2117" class="sample-page menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children menu-item-2117"><a href="/sample-page-2/">サンプルページ</a></li>
            <li id="menu-item-2118" class="menu-item menu-item-type-post_type menu-item-object-post menu-item-2118"><a href="/2017/06/01/hello-world/">Hello world!</a></li>
            <li id="menu-item-2119" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-2119"><a href="http://yahoo.co.jp">Yahoo!</a></li>
            <li id="menu-item-2120" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-2120"><a href="/category/%e3%83%9e%e3%83%bc%e3%82%af%e3%82%a2%e3%83%83%e3%83%97/">マークアップ</a></li>
        </ul>
    </div>
</div>

ご覧の通り、4行目のli要素にclass名sample-pageが追加されていることが分かります。とても便利な機能ですので活用してみてください。

まとめ

長々とカスタムメニューについて説明してみましたが、どのような記述をすればどのようなソースコードを書き出されるのか、を理解しておけば、実際のどんなデザインが実現可能なのかを把握しておくことも可能です。

個人的な経験ですが、デザイン在りきの制作の場合、デザインを優先するがためにカスタムメニューという機能を捨てざるを得ない場合が過去にありました。

それは確かにクライアントの望んでいるデザインだったのでしょうが、それと同じように「クライアントが管理しやすいカスタムメニュー機能」を提案の一つに入れることも、クライアントにとって有意義となる可能性もあります。

私がディレクションして制作してきたWordPressを利用したウェブサイトに関しては、過去にもほぼすべてにカスタムメニュー機能を実装してきました。

それは、管理されるのが私たちのような専門家ではなく、クライアントさんであることが多いという点もあるかもしれません。

比較的豊富な予算をお持ちのクライアントさんの場合であれば、管理も請け負うこともできますので、メニュー構造の変更など技術があれば誰でもできます。

しかし、それほど豊富な予算を持たず、管理・運営はできる限り自分たちで行いたいというクライアントさんも多くみえます。そういった方々のことを考えた際に、メニュー項目の修正に毎度修正費用を負ってもらい専門家が修正する流れよりも、クライアントさん側で修正しトライ&エラーができる環境の方が双方においても有意義だと僕は考えています。

こういった便利な機能をしっかりと提案して活用しながら、クライアント自身が触りやす・扱いやすいウェブサイトを提供していく必要があるのではないかと日々思うわけです。

今回のカスタムメニュー機能もぜひご利用ください。

こちらの書籍がとても参考になりました

WordPress 6.5.x 対応版を出版しました

WordPress デフォルトテーマ Twenty Twenty-Four を使って、シンプルなブログやポートフォリオサイト、そしてコーポレートサイトを作りながら、ブロックテーマやサイトエディターの基本を理解することができます。