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

はじめまして、toriと申します。
つい最近wpを知って、こちらのサイトで勉強させていただいております。
「WordPressのナビゲーションメニューを等幅表示してみる」の記事も、非常に気になっていて修正したいと考えていた内容でしたので、参考にさせていただきました。
が、どうしても修正することができません。
注意点等あれば、是非ともご教示ください。
WordPress 3.2.1 Twenty Ten 使用です。
toriさん、はじめまして。
返信遅くなりました。
等幅表示用のclassであるmenu-items-num-*はhtmlのソースに存在しているでしょうか?
Twenty Tenのナビゲーションはメニューの登録がないと、固定ページリスト表示するテンプレートタグが利用されるようになっていて、仕様が大幅に変わるため、等幅の表示はできません。
メニューの登録状態、HTMLソース、PHPの記述内容など今一度確認してみてください。
ご丁寧な返信ありがとうございます。
お礼が大変遅くなりまして申し訳ありません。
結論から申しますと、等幅表示用のclassは用意していたのですが、用意していた以上のナビゲーションメニュー数だったというのが原因でした。
classを用意したところ、問題無く等幅表示されました。
ご教示ありがとうございました。
はじめまして、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です。
$args['container_class'] = $class;という部分のコードを調整していただければ可能です。