[WordPress] カスタムメニューで表示されるメニューテキストを画像に置き換えて表示する方法(カレント機能付き)
カスタムメニューでメニュー部分を画像で表示したい場合、CSS で画像を置き換えることもできますが、直接置くことができないかやってみた所なんとか自分のやりたい要件を満たし画像の表示ができたので、その方法をまとめました。(子メニューは1階層のみ対応です。)
2種類の方法を作りましたが、子メニューの表示がなかなか上手く行きませんでした…。1つ目は子メニュー部分は入れ子にせず、子メニューリスト要素へ child というクラスを振るという方法です。2つ目の方法は子メニュー部分は ul 要素で入れ子になりますが、子メニュー要素のまとまりが1つだけでないとエラーになってしまうのでご注意下さい。
1. メニュー画像を表示するコード(子メニューにはクラス付けをする)
このコードでは、HTML で表示する画像の名前が 「menu_item1.png」などになります。数字の部分は管理画面で設定したメニューの順番が付けられるので、それに合わせて画像の名前を変更して下さい。
管理画面で以下のようなメニューを作ります。(add_theme_support( ‘menus’ );)だけ先に functions.php へ記入しないと作れません。メニューの名前は wp_get_nav_menu_items の引数となります。

以下のコードを functions.php へ記入します。
// カスタムメニュー機能を有効にする
add_theme_support( 'menus' );
// カスタムメニューを画像に置き換えるコード
function nav_menu_image(){
$items = wp_get_nav_menu_items('global');
// ↑ 引数に管理画面で作成したカスタムメニューの名前を記入
$cnt = 0;
$format = '.png';
// ↑メニュー画像の拡張子をドット付きで記入
$current = (empty($_SERVER["HTTPS"]) ? "http://" : "https://").$_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"];
// ↑ 現在のアドレスを取得
foreach($items as $item){
$cnt++;
$url = esc_html($item -> url);
$title = esc_html($item -> title);
$child_item = esc_html($item -> menu_item_parent);
// ↑ $item よりメニューのURL・ラベル名・親メニューIDを取得
if($url === $current && $child_item === '0'){
// ↑ 現在のURLとメニューのURLが一致かつ親メニューを持たない場合の処理
echo '<li class="current"><a href="'.$url.'"><img src="'.get_template_directory_uri().'/images/menu_item'.$cnt.$format.'" alt="'.$title.'"></a></li>'.PHP_EOL;
} else if($child_item === '0') {
// ↑ 親メニューを持たないメニューの場合の処理
echo '<li><a href="'.$url.'"><img src="'.get_template_directory_uri().'/images/menu_item'.$cnt.$format.'" alt="'.$title.'"></a></li>'.PHP_EOL;
} else {
if(!empty($child_item) && $url === $current){
// ↑ 親メニューを持ち、現在のURLとメニューのURLが一致する場合の処理
echo '<li class="child current"><a href="'.$url.'">'.$title.'</a></li>'.PHP_EOL;
} else {
// ↑ 親メニューを持つメニューの場合
echo '<li class="child"><a href="'.$url.'">'.$title.'</a></li>'.PHP_EOL;
}
}
}
}
6行目の wp_get_nav_menu_items() 関数で WP_Post オブジェクトの配列を取得することができます。
8行目には表示したい画像のファイル名をドット付きで記入します。
表示中ページのメニューには current というクラスが付きます。現在のページ URL を取得し、メニューにリンクされている URL と一致した場合にクラスを振るようにしています。
カスタムメニューを表示したいテンプレートファイルへ以下を記入します。
<ul> <?php nav_menu_image(); ?> </ul
表示されるソースコード
これで以下のようなソースコードが表示されるようになります。画像の alt 属性には管理画面で設定したラベル名が表示されます。

2. メニュー画像を表示するコード(子メニューは ul 要素で入れ子にするが子メニューは1まとまりまで)
1 のコードと同じように、HTML で表示する画像の名前は「menu_item1.png」などになります。数字の部分は管理画面で設定したメニューの順番が付けられるので、それに合わせて画像の名前を変更して下さい。
このコードでは、子メニューは画像にしていませんが、子メニューも画像にしたい場合は、39、43行目のaタグの中身を、.$title. から
<img src="'.get_template_directory_uri().'/images/menu_item'.$cnt.$format.'" alt="'.$title.'">
へ変更して下さい。
管理画面で以下のようなメニューを作ります。

以下のコードを functions.php へ記入します。
// カスタムメニュー機能を有効にする
add_theme_support( 'menus' );
// カスタムメニューを画像に置き換えるコード
function nav_menu_image(){
$items = wp_get_nav_menu_items('global');
// ↑ 引数に管理画面で作成したカスタムメニューの名前を記入
$format = '.png';
// ↑メニュー画像の拡張子をドット付きで記入
$current = (empty($_SERVER["HTTPS"]) ? "http://" : "https://").$_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"];
// ↑ 現在のアドレスを取得
$item_list = array();
$child_item_frag = '';
$cnt = 1;
$child_cnt = 0;
// ↑ 変数の初期化
foreach($items as $item){
$url = esc_html($item -> url);
$title = esc_html($item -> title);
$child_item = esc_html($item -> menu_item_parent);
// ↑ $item よりメニューのURL・ラベル名・親メニューIDを取得
// まずメニュー表示の元になる配列を作る
if($url === $current && $child_item === '0'){
// ↑ 現在のURLとメニューのURLが一致かつ親メニューを持たない場合の処理
$item_lists[] = '<li class="current"><a href="'.$url.'"><img src="'.get_template_directory_uri().'/images/menu_item'.$cnt.$format.'" alt="'.$title.'"></a></li>'.PHP_EOL;
} else if($child_item == 0) {
// ↑ 親メニューを持たないメニューの場合の処理
$item_lists[] = '<li><a href="'.$url.'"><img src="'.get_template_directory_uri().'/images/menu_item'.$cnt.$format.'" alt="'.$title.'"></a></li>'.PHP_EOL;
} else {
if($child_item_frag == $child_item_frag && $url === $current){
// ↑ 親メニューを持ち、現在のURLとメニューのURLが一致する場合の処理
$item_lists[$child_cnt][] = '<li class="current"><a href="'.$url.'">'.$title.'</a></li>'.PHP_EOL;
$child_cnt--;
} else if($child_item_frag == $child_item_frag) {
// ↑ 親メニューを持つメニューの場合の処理
$item_lists[$child_cnt][] = '<li><a href="'.$url.'">'.$title.'</a></li>'.PHP_EOL;
$child_cnt--;
}
$child_item_frag = $child_item;
}
$cnt++;
$child_cnt++;
}
// 作った配列から表示する
foreach($item_lists as $item_list){
if(!is_array($item_list)){
// 子メニューを持たないメニューを表示
echo $item_list;
};
if(is_array($item_list)){
// 子メニューを持つメニューを表示
echo '<ul class="child_menu">'.PHP_EOL;
foreach($item_list as $child){
echo $child;
}
echo '</ul>'.PHP_EOL;
}
}
}
カスタムメニューを表示したいテンプレートファイルへ以下を記入します。
<ul> <?php nav_menu_image(); ?> </ul
表示されるソースコード
これで以下のようなソースコードが表示されるようになります。

子メニューの入れ子が1つまでしか対応出来なかったのは、子メニューは配列を入れ子にして、同じ親メニューIDをもつ場合は同じ入れ子の配列に入れるというのが上手く行かなかったからです。もっと多次元配列とか勉強しようと思いました…。
No Comments & Tracbacks