WordPressのナビゲーションメニューを等幅表示してみる

WordPressのナビゲーションメニューを等幅表示してみる

WordPressで登録されているウィジェットの数に応じたclassを出力するWordPressで同一エリアのウィジェットエリア表示に応じたClassを出力するに引き続き、今回はナビゲーションメニューを等幅で表示できるようにしてみます。

やり方は、前回までと同じようにナビゲーションの表示数をカウントし、それに応じた class を出力。前もって css で定義していた width で表示という手法。

ウィジェットの場合は、別途 class 出力用の関数を作成しテンプレートに追加する必要がありましたが、ナビゲーションメニューの場合は、パラメータでラッパー要素の指定が出来、なおかつ、wp_nav_menu_argsフックにてパラメータのフィルタリングが可能となっています。

修正する手間はなるべく掛けない方が良いに決まっていますから、今回はテンプレートファイルの修正は行わず、ラッパー要素の class に対し、メニュー数の判定ができる class を出力してみるようにします。

CODE 1をペタっとテーマのfunctions.php に追加するか、独自のプラグインに含めてもらえれば、menu-items-num-* (* はメニューの数)といった class が追加されるようになります。

CODE 1

function add_nav_menu_num_class( $args ) {

	$menu = wp_get_nav_menu_object( $args['menu'] );

	// Get the nav menu based on the theme_location
	if ( ! $menu && $args['theme_location'] && ( $locations = get_nav_menu_locations() ) && isset( $locations[$args['theme_location']] ) ) {
		$menu = wp_get_nav_menu_object( $locations[$args['theme_location']] );
	}

	// get the first menu that has items if we still can't find a menu
	if ( ! $menu && ! $args['theme_location'] ) {
		$menus = wp_get_nav_menus();
		foreach ( $menus as $menu_maybe ) {
			if ( $menu_items = wp_get_nav_menu_items( $menu_maybe->term_id ) ) {
				$menu = $menu_maybe;
				break;
			}
		}
	}

	if ( $menu && ! is_wp_error( $menu ) && ! isset( $menu_items ) ) {
		$menu_items = wp_get_nav_menu_items( $menu->term_id );
	}

	if ( ! empty( $menu_items ) ) {
		$count = 0;
		foreach ( $menu_items as $menu_item ) {
			if ( $menu_item->menu_item_parent == '0' ) {
				$count++;
			}
		}

		$class = 'menu-items-num-' . $count;

		if ( $args['container'] ) {
			if ( $args['container_class'] ) {
				$args['container_class'] .= ' ' . $class;
			} else {
				$args['container_class'] = $class;
			}
		} else {
			if ( $args['menu_class'] ) {
				$args['menu_class'] .= ' ' . $class;
			} else {
				$args['menu_class'] = $class;
			}
		}
	} elseif ( ( ! $menu || is_wp_error( $menu ) || ( isset( $menu_items ) && empty( $menu_items ) && ! $args['theme_location'] ) ) && $args['fallback_cb'] == 'wp_page_menu' ) {
		$count = 0;
		$defaults = array('sort_column' => 'menu_order, post_title', 'menu_class' => 'menu', 'echo' => true, 'link_before' => '', 'link_after' => '');
		$list_args = wp_parse_args( $args, $defaults );
		$list_args = apply_filters( 'wp_page_menu_args', $list_args );
		
		if ( ! empty( $list_args['show_home'] ) ) {
			if ( get_option( 'show_on_front' ) == 'page' ) {
				if ( ! empty( $list_args['exclude'] ) ) {
					$list_args['exclude'] .= ',';
				} else {
					$list_args['exclude'] = '';
				}
				$list_args['exclude'] .= get_option( 'page_on_front' );
			}
			$count = 1;
		}
		
		$defaults = array(
			'depth' => 0, 'show_date' => '',
			'date_format' => get_option('date_format'),
			'child_of' => 0, 'exclude' => '',
			'title_li' => __('Pages'), 'echo' => 1,
			'authors' => '', 'sort_column' => 'menu_order, post_title',
			'link_before' => '', 'link_after' => '', 'walker' => '',
		);
		$list_args = wp_parse_args( $list_args, $defaults );
		$list_args['exclude'] = preg_replace( '/[^0-9,]/', '', $list_args['exclude'] );
		$exclude_array = ( $list_args['exclude'] ) ? explode(',', $list_args['exclude']) : array();
		$list_args['exclude'] = implode( ',', apply_filters( 'wp_list_pages_excludes', $exclude_array ) );

		// Query pages.
		$list_args['hierarchical'] = 0;
		$pages = get_pages( $list_args );
		if ( $pages ) {
			foreach ( $pages as $page ) {
				if ( $page->post_parent === 0 ) {
					$count++;
				}
			}
		}

		if ( $args['menu_class'] ) {
			$args['menu_class'] .= ' ' . 'menu-items-num-' . $count;
		} else {
			$args['menu_class'] = 'menu-items-num-' . $count;
		}
	}

	return $args;
}
add_filter( 'wp_nav_menu_args', 'add_nav_menu_num_class' );

実際のhtmlとして出力されるコードは、CODE 2のようになります。

CODE 2

<div class="menu-header menu-items-num-5">
<div class="menu menu-items-num-3">

Twenty Tenの場合の CSS 記述例はCODE 3

CODE 3

.menu-items-num-3 a {
	width: 289px;
}

.menu-items-num-4 a {
	width: 212px;
}

.menu-items-num-5 a {
	width: 165px;
}

.menu-items-num-6 a {
	width: 134px;
}

.menu-items-num-7 a {
	width: 112px;
}

適用してみた場合とデフォルトの表示表示を比較してみると、メニューの間隔が等間隔になって、見た目のバランスが良くなっているのが分かりますね。

ナビゲーションメニュー等幅表示適用前後比較

「WordPressのナビゲーションメニューを等幅表示してみる」への5件のフィードバック

  1. はじめまして、toriと申します。

    つい最近wpを知って、こちらのサイトで勉強させていただいております。

    「WordPressのナビゲーションメニューを等幅表示してみる」の記事も、非常に気になっていて修正したいと考えていた内容でしたので、参考にさせていただきました。

    が、どうしても修正することができません。
    注意点等あれば、是非ともご教示ください。

    WordPress 3.2.1 Twenty Ten 使用です。

  2. toriさん、はじめまして。

    返信遅くなりました。
    等幅表示用のclassであるmenu-items-num-*はhtmlのソースに存在しているでしょうか?
    Twenty Tenのナビゲーションはメニューの登録がないと、固定ページリスト表示するテンプレートタグが利用されるようになっていて、仕様が大幅に変わるため、等幅の表示はできません。

    メニューの登録状態、HTMLソース、PHPの記述内容など今一度確認してみてください。

  3. ご丁寧な返信ありがとうございます。
    お礼が大変遅くなりまして申し訳ありません。

    結論から申しますと、等幅表示用のclassは用意していたのですが、用意していた以上のナビゲーションメニュー数だったというのが原因でした。

    classを用意したところ、問題無く等幅表示されました。

    ご教示ありがとうございました。

  4. はじめまして、yamaともうします。
    twenty fourteenで利用させていただいたのですが、div class=”menu-header” のところ、twenty fourteenだとdiv class=”menu-head-container”になるのですが、このclassのパラメータが、たとえばclass=”menu-head-container menu-items-num-5″ となってほしいところがclass=”menu-items-num-5″となってしまいます。 WordPress 3.9.2 phpは3.4です。

  5. $args['container_class'] = $class;
    という部分のコードを調整していただければ可能です。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です