WordPress サブ ページ メニュー ウィジェット

WordPress で親ページに子ページのメニューを表示するウィジェットを作成してみました。

コーポレート サイトなどでは、固定ページに階層をもたせるケースが結構あるとおもいます。この場合、親ページ(「会社案内」等)に子ページ(「会社概要」、「沿革」等)へのメニューがあるとユーザリビティが良いのではないでしょうか。

そんなメニューを表示するウィジェットです。

仕様

  • 階層構造ではない場合、ウィジェット自体を表示しない。
  • 親ページ(トップ階層)の場合、その階層下をメニュー表示する。
  • 子ページの場合、親ページの階層下をメニュー表示する。

2016-08-24-subpage-menu-widget

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 はカスタム メニュー ウィジェットとほぼ同じで、テーマのスタイルが反映される場合もあります。反映されない場合は、カスタム メニュー ウィジェットのスタイルを参考に追加してください。

コメントを残す

メールアドレスが公開されることはありません。

日本語でコメントを入力してください。(スパム対策)