WordPress で親ページに子ページのメニューを表示するウィジェットを作成してみました。
コーポレート サイトなどでは、固定ページに階層をもたせるケースが結構あるとおもいます。この場合、親ページ(「会社案内」等)に子ページ(「会社概要」、「沿革」等)へのメニューがあるとユーザリビティが良いのではないでしょうか。
そんなメニューを表示するウィジェットです。
仕様
- 階層構造ではない場合、ウィジェット自体を表示しない。
- 親ページ(トップ階層)の場合、その階層下をメニュー表示する。
- 子ページの場合、親ページの階層下をメニュー表示する。
functions.php
functions.php などに下記のコードを記述します。
class Widget_Sub_Page_Menu extends WP_Widget {
function __construct() {
$widget_ops = array( 'classname' => 'widget_subpagemenu', 'description' => 'サブページのメニュー' );
parent::__construct( 'subpagemenu', 'サブページメニュー', $widget_ops );
$this->alt_option_name = 'widget_subpagemenu';
add_action( 'save_post', array( $this, 'flush_widget_cache' ) );
add_action( 'deleted_post', array( $this, 'flush_widget_cache' ) );
add_action( 'switch_theme', array( $this, 'flush_widget_cache' ) );
}
function widget( $args, $instance ) {
global $post;
extract($args);
$title = apply_filters( 'widget_title', $instance['title'] );
$depth = $instance['depth'];
$show_parent = $instance['show_parent'];
$title_parent = $instance['title_parent'];
if ( $post ) {
if ( $post->post_parent ) {
$children = wp_list_pages( 'title_li=&depth=' . $depth . '&child_of=' . $post->post_parent . '&echo=0&sort_column=menu_order' );
$parent_page = get_page( $post->post_parent );
} else {
$children = wp_list_pages( 'title_li=&depth=' . $depth . '&child_of=' . $post->ID . '&echo=0&sort_column=menu_order' );
$parent_page = get_page( $post->ID );
}
if ( $children ) {
echo $before_widget;
if ( $title_parent ) {
echo $before_title . $parent_page->post_title . $after_title;
} else {
if ( $title ) echo $before_title . $title . $after_title;
}
echo '<div class="menu-main-container">';
echo '<ul class="menu">';
if ( $show_parent ) {
echo '<li class="menu-item"><a href="' . esc_url( get_permalink( $parent_page->ID) ) . '">' . esc_html( $parent_page->post_title ) . '</a><ul>';
echo $children;
echo '</ul></li>';
} else {
echo $children;
}
echo '</ul>';
echo '</div>';
echo $after_widget;
}
}
}
function update( $new_instance, $old_instance ) {
$instance = $old_instance;
$instance['title'] = strip_tags( $new_instance['title'] );
$instance['depth'] = strip_tags( $new_instance['depth'] );
$instance['show_parent'] = strip_tags( $new_instance['show_parent'] );
$instance['title_parent'] = strip_tags( $new_instance['title_parent'] );
$this->flush_widget_cache();
$alloptions = wp_cache_get( 'alloptions', 'options' );
if ( isset($alloptions['widget_subpagemenu'] ) )
delete_option( 'widget_subpagemenu' );
return $instance;
}
function flush_widget_cache() {
wp_cache_delete( 'widget_subpagemenu', 'widget' );
}
function form( $instance ) {
$title = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : '';
$depth = isset( $instance['depth'] ) ? intval( $instance['depth'] ) : 1;
$show_parent = isset( $instance['show_parent'] ) ? (bool)( $instance['show_parent'] ) : false;
$title_parent = isset( $instance['title_parent'] ) ? (bool)( $instance['title_parent'] ) : false;
echo '<p><label for="' . $this->get_field_id( 'title' ) . '">' . __( 'Title:' ) . '</label>';
echo '<input class="widefat" id="' . $this->get_field_id( 'title' ) . '" name="' . $this->get_field_name( 'title' ) . '" type="text" value="' . $title . '" /></p>';
echo '<p><label for="' . $this->get_field_id( 'depth' ) . '">階層数:</label>';
echo '<input id="' . $this->get_field_id( 'depth' ) . '" name="'.$this->get_field_name( 'depth' ) . '" type="text" value="' . $depth . '" size="3" /></p>';
echo '<p><input type="checkbox" class="checkbox" id="' . $this->get_field_id( 'show_parent' ) .'" name="' . $this->get_field_name( 'show_parent' ) .'" ' . checked($show_parent, true, false) . ' /> ';
echo '<label for="' . $this->get_field_id( 'show_parent' ) . '">親ページをメニューに含める</label></p>';
echo '<p><input type="checkbox" class="checkbox" id="' . $this->get_field_id( 'title_parent' ) .'" name="' . $this->get_field_name( 'title_parent' ) .'" ' . checked($title_parent, true, false) . ' /> ';
echo '<label for="' . $this->get_field_id( 'title_parent' ) . '">タイトルに親ページのタイトルを表示</label></p>';
}
}
add_action( 'widgets_init', function() { register_widget( 'Widget_Sub_Page_Menu' ); } );
スタイル(CSS)
出力する HTML はカスタム メニュー ウィジェットとほぼ同じで、テーマのスタイルが反映される場合もあります。反映されない場合は、カスタム メニュー ウィジェットのスタイルを参考に追加してください。