【ワードプレス】テーマの作り方⑥:ウィジェットを自作する

ワードプレステーマの作り方⑥のアイキャッチ

前回はウィジェットエリアを作成し、ウィジェットを表示する方法について解説しました。

ワードプレステーマの作り方⑤のアイキャッチ【ワードプレス】テーマの作り方⑤:ページにウィジェットを表示する

今回はこのウィジェット本体を自作する方法について解説します。

ウィジェットはページにウィジェットの内容を表示するだけでなく、ダッシュボードから設定を変更することも可能です。さらにその設定の変更をウィジェットに反映することで、表示されるウィジェットの内容を変更することも可能です。

つまり、ウィジェットは下記の3つの機能を持ってます。

  • ページに表示する
  • 設定変更を受け付ける
  • 受け付けた設定を反映する

このページでは、この3つの機能を持つウィジェットの作成方法を解説していきます。

ウィジェットの作り方

では早速ウィジェットを作る方法について解説していきたいと思います。

ウィジェットを作成する手順

ワードプレスでのウィジェット作成の手順は下記となります。

  1. ワードプレス に用意されているウィジェットクラス(WP_Widget)を親クラスとしたサブクラスを定義
  2. 下記の4つのメソッドをオーバーライド(親クラスのメソッドを上書き)
    • __construct
    • widget
    • form
    • update
  3. ウィジェットを登録する関数を自作し、その関数の中で register_widget 関数を定義したサブクラス名を引数として実行
  4. アクションフック “widgets_init’ に自作した関数をフック

これらの処理を functions.php の中に記述することで、ウィジェットを作成することができます。

ウィジェットを作成するだけのプログラム

最も簡単なウィジェット(タイトルを表示するだけのウィジェット)を作成するプログラムが下記になります。

functions.php
<?php
/**
 * テストウィジェット
 */
class Test_Widget extends WP_Widget {

	/**
	 * テストウィジェットのコンストラクタ
	 */
	public function __construct() {
		parent::__construct(
			'test_widget', // Base ID.
			'テストウィジェット', // Name.
			array( 'description' => 'テスト用のウィジェットです' ) // Args.
		);
	}

	/**
	 * ウィジェットのページ表示を行う関数
	 *
	 * @param array $args : ウィジェットの設定.
	 * @param array $instance : ウィジェットのインスタンス.
	 */
	public function widget( $args, $instance ) {
		/* ここからregister_sidebarに入力されたHTMLを出力 */

		/* before_widgetを出力 */
		echo $args['before_widget'];

		/* before_titleとafter_titleを出力 */
		if ( ! empty( $args['widget_name'] ) ) {
			/* タイトルが設定されている場合のみ出力 */
			echo $args['before_title'] . apply_filters( 'widget_title', $args['widget_name'] ) . $args['after_title'];
		}

		/* ここにウィジェットに表示する内容を記述 */

		/* 最後にafter_widgetを出力 */
		echo $args['after_widget'];
	}

	/**
	 * ウィジェットの設定フォームを表示する関数
	 *
	 * @param array $instance : ウィジェットのインスタンス.
	 */
	public function form( $instance ) {

	}

	/**
	 * ウィジェットの設定更新を行う関数
	 *
	 * @param array $new_instance : ウィジェットの元々のインスタンス.
	 * @param array $old_instance : ウィジェットの新しいインスタンス.
	 */
	public function update( $new_instance, $old_instance ) {

	}

}

/**
 * ウィジェット作成関数
 */
function register_my_widgets() {
	register_widget( 'Test_Widget' );
}

/* widgets_initフックにウィジェット作成関数をフック */
add_action( 'widgets_init', 'register_my_widgets' );
>

ダッシュボード(ワードプレス管理画面)から「外観」→「ウィジェット」と辿ることでウィジェットの設定画面を表示することができますが、上記プログラムを functions.php に記述しておくと、parent::__constructで指定した「テストウィジェット」という名前のウィジェットが追加で表示されるようになります。

作成したウィジェットが設定画面に表示される様子

その下には parent::__construct で指定した「テスト用のウィジェットです」という説明文も表示されていることが確認できると思います。

このウィジェットをサイドバーに表示するウィジェットエリアに登録してやれば、ページを表示すると下のようにタイトルだけ表示されるウィジェットが表示されるようになることが確認できます。

作成したウィジェットがページに表示される様子

手順とプログラムの対応

前述のウィジェット作成の各手順とプログラムの対応は下記の通りです。

手順 1.

手順 1. に対応するプログラムは下記となります。

/**
 * テストウィジェット
 */
class Test_Widget extends WP_Widget {
	/* 略 */
}

class クラス名 extends WP_Widgetと記述することで、WP_Widget を親クラスとしたサブクラスを定義することができます。

WP_Widget クラスはウィジェットを作成・表示するために必要な処理をもつ、ワードプレスに予め用意されているクラスです。このクラスの一部分を手順 2. のメソッドのオーバーライドで上書きして変更することで、少量のソースコード記述で様々なウィジェットを作成できる仕組みとなっています。

手順 2.

手順 2. に対応するプログラムは下記となります。

public function __construct() {
	/* 〜略〜 */
}

public function widget( $args, $instance ) {
	/* 〜略〜 */
}

public function form( $instance ) {

}

public function update( $new_instance, $old_instance ) {

}

親クラスに用意されている上記の4つのメソッドを、作成したサブクラス用に上書きする記述となります。それぞれのメソッドは下記の役割を果たします。後半の3つメソッドが、前述したウィジェットの機能の3つそれぞれに該当します。

  • __construct:ウィジェットの実体を作成する
  • widget:ウィジェットの内容をページに表示する
  • form:作成したウィジェットの設定フォームを表示して設定変更を受け付ける
  • update:受け付けた設定変更をウィジェットに反映する

widget、formと update に関しては図で見た方がイメージがつきやすいと思います。

widget メソッドは下の図のようにウィジェットの内容をページに表示します。

widgetメソッドの処理

ですので、widget メソッドを作り込むことで、自分好みのウィジェット表示が行うことが可能です。

form メソッドは下の図のようにダッシュボードのウィジェット設定画面の設定フォームを表示し、ユーザーから設定変更を受け付けます

formメソッドの処理

さらにこのフォームで受け付けた設定を update メソッドがウィジェットの新たな設定値としてウィジェットに反映します(update メソッドの戻り値が新たな設定値となります)。

これにより、次の widget メソッドで実行時には update メソッドで更新された設定に従ってウィジェットが表示されます。

updateメソッドの処理

さらに、これらのメソッドは __construct メソッドでウィジェットの実体によって実行されます。

手順 3.

手順 3. に対応するプログラムは下記部分です。

/**
 * ウィジェット作成関数
 */
function register_my_widgets() {
	register_widget( 'Test_Widget' );
}

register_widget 関数に作成するウィジェットのサブクラス名を指定して実行することで、ワードプレスにウィジェットが新たなウィジェットとして登録されます。

これによりウィジェット設定画面に作成したウィジェットが表示され、ウィジェットエリアへの登録が行えるようになります。

手順 4.

手順 4. に対応するプログラム部分は下記の部分です。

add_action( 'widgets_init', 'register_my_widgets' );

widgets_init アクションフックに、手順 3. で作成した関数をフックします。これによりワードプレスの起動中に自動的にこの関数が実行され、ウィジェットがワードプレス に登録されます。

フックに関しては下記で解説していますので、詳しく知りたい方は是非読んでみてください。

ワードプレスのフック解説ページのアイキャッチワードプレスのフックとは?使い方は?初心者向けに分かりやすく解説します!

自作ウィジェットの例1(設定値なし)

ここまではウィジェットを作成するだけのプログラムを紹介して、ウィジェットを作成するための手順について解説しました。

ここからは、もう少しまともなウィジェットを作成する例を示し、特に手順 2. で出てきたオーバーライドする各メソッドにどのようなプログラムを記述すれば良いかの詳細を説明していきたいと思います。

まずは設定値を持たない自作ウィジェットの例を示し、特に __construct と widget メソッドに記述が必要なプログラムを示していきたいと思います。

記事一覧表示ウィジェット(設定値なし)

下記は記事の一覧を表示するウィジェット(設定値なし)を作成するプログラムになります。

<?php
/**
 * Adds RecentPost_Widget widget.
 */
class RecentPost_Widget extends WP_Widget {

	/**
	 * ウィジェットの実体を作成
	 */
	public function __construct() {
		parent::__construct(
			'recent_post_widget', // Base ID.
			__( '自作の記事一覧', 'text_domain' ), // Name.
			array( 'description' => __( '記事のリストを表示します', 'text_domain' ) ) // Args.
		);
	}

	/**
	 * ウィジェットのフロントエンド表示
	 *
	 * @see WP_Widget::widget()
	 *
	 * @param array $args     ウィジェットの引数.
	 * @param array $instance データベースに保存されている設定値.
	 */
	public function widget( $args, $instance ) {
		/* ここからregister_sidebarに入力されたHTMLを出力 */

		/* before_widgetを出力 */
		echo $args['before_widget'];

		/* before_titleとafter_titleを出力 */
		if ( ! empty( $instance['title'] ) ) {
			/* タイトルが設定されている場合は設定されたタイトルを表示 */
			echo $args['before_title'] . apply_filters( 'widget_title', $args['widget_name'] ) . $args['after_title'];
		} else {
			/* タイトルが設定されていない場合はデフォルトのタイトルを表示 */
			echo $args['before_title'] . '自作の記事一覧' . $args['after_title'];
		}

		/* ここから記事一覧の表示 */

		/* サブクエリを作成 */
		$sub_args = array(
			'orderby'        => 'date',
			'order'          => 'DESC',
			'posts_per_page' => 5,
		);

		/* データベースからデータ取得 */
		$my_query = new WP_Query( $sub_args );

		/* 記事のタイトルをリスト形式で表示 */
		echo '<ul>';
		while ( $my_query->have_posts() ) {
			$my_query->the_post();
			$page_title = get_the_title();
			echo '<li>' . $page_title . '</li>';
		}
		echo '</ul>';

		wp_reset_postdata();

		/* 最後にafter_widgetを出力 */
		echo $args['after_widget'];
	}

	/**
	 * ウィジェットの更新フォームを表示する関数
	 *
	 * @see WP_Widget::form()
	 *
	 * @param array $instance データベースに保存されている設定値.
	 */
	public function form( $instance ) {

	}

	/**
	 * ウィジェットの設定更新を行う関数
	 *
	 * @see WP_Widget::update
	 *
	 * @param array $new_instance : ウィジェットの元々のインスタンス.
	 * @param array $old_instance : ウィジェットの新しいインスタンス.
	 */
	public function update( $new_instance, $old_instance ) {

	}
}

/**
 * ウィジェット作成関数
 */
function register_my_widgets() {
	register_widget( 'RecentPost_Widget' );
}

/* widgets_initフックにウィジェット作成関数をフック */
add_action( 'widgets_init', 'register_my_widgets' );
?>

上記プログラムを functions.php に記述し、ウィジェット設定画面でウィジェットエリアに追加すれば、下のようにウィジェットが表示されます。

記事一覧ウィジェットの表示例

しかし、設定値を持っていないので、ウィジェット設定画面でウィジェットの設定はできない状態です(設定値を持つウィジェットの例は後半の自作ウィジェットの例2(設定値あり)で紹介します)。

設定値を持たない場合の設定フォームの例

__construct メソッド

__construct メソッドはウィジェットの実体を作成するコンストラクタです。ページ内のウィジェットの表示時やウィジェットの設定画面表示時に毎回このメソッドが実行され、ウィジェットの実体が作成されます。

このメソッドでは下記を行います。

  • 親クラスのコンストラクタを呼び出す

具体的には下記を実行します。

parent::__construct(
   'Base ID', 'ウィジェット名'
);

第1引数はウィジェットの ID のベースとなる ID を指定します。第2引数はウィジェットの名前を指定します。このウィジェットの名前がウィジェット設定画面に表示されます。これらの2つの引数は必須の引数となります。

また第3引数や第4引数として、さらに詳細なウィジェットの設定を渡すことも可能です。

widget メソッド

widget メソッドはページにウィジェットを表示します。この widget メソッドには下記を記述します。

  • ウィジェットに表示する内容を出力する

widget はまさにウィジェットの本体を作成するメソッドですので、基本的に作りたいウィジェットに合わせて作成すれば良いです。

例えば、上記プログラムではサブクエリを作成して投稿データを取得し、タイトルのみを列挙することで、記事一覧を表示するウィジェットを実現しています。サブクエリについては下記で解説していますので詳しく知りたい方はこちらをご参照ください。

クエリー解説ページのアイキャッチワードプレスのクエリとは?メインクエリとサブクエリの違いは?

基本的に自由に作成すれば良い widget メソッドですが、一つだけポイントがあります。それは、ウィジェットが登録されるウィジェットエリアの設定値を反映するように作成することです。

ウィジェットエリアを作成する際には register_sidebar 関数が実行され、様々な設定値が指定されます。特に widget メソッドで意識すべき設定は下記の4つです。

    • ‘before_widget’:各ウィジェットの前に記述する HTML
    • ‘after_widget’:各ウィジェットの後ろに記述する HTML
    • ‘before_title’:各ウィジェットタイトルの前に記述する HTML
  • ‘after_title’:各ウィジェットタイトルの前に記述する HTML

つまり、ウィジェットの最初と最後には ‘before_widget’ と ‘after_widget’ で指定される HTML 文を出力し、タイトルの前後には ‘before_title’ と ‘after_title’ で指定される HTML 文を出力する必要があります。逆にこれを行わないと、作成したウィジェットのみウィジェットエリアに指定された設定が適用されず、このウィジェットのみスタイルが適用されず見た目が異なってしまうような問題が発生してしまいます。

これらの HTML 文を出力しているのは下記の部分です。この部分はどのウィジェットにもそのまま適用しても良いと思います。

/* before_widgetを出力 */
echo $args['before_widget'];

/* before_titleとafter_titleを出力 */
if ( ! empty( $instance['title'] ) ) {
	/* タイトルが設定されている場合は設定されたタイトルを表示 */
	echo $args['before_title'] . apply_filters( 'widget_title', $args['widget_name'] ) . $args['after_title'];
} else {
	/* タイトルが設定されていない場合はデフォルトのタイトルを表示 */
	echo $args['before_title'] . '自作の記事一覧' . $args['after_title'];
}

/* 略 */

/* 最後にafter_widgetを出力 */
echo $args['after_widget'];

ただし、タイトルをウィジェット設定画面で変更できるようにするような場合はタイトル出力部分のみは変更しても良いです。これを行なっているプログラムは後述の自作ウィジェットの例2(設定値あり)で紹介していますので、こちらも是非見てみてください。

form メソッド

設定値がない場合、form メソッドでは何も行う必要はありません。

update メソッド

設定値がない場合、update メソッドでは何も行う必要はありません。

スポンサーリンク

自作ウィジェットの例2(設定値あり)

次は設定値を持つウィジェットの例を示します。

今度は form と update メソッドを設定値に応じて作成する必要があります。さらに、その設定値を反映するために widget メソッドも変更する必要があります。

記事一覧表示ウィジェット(設定値あり)

設定値ありのウィジェットを作成する場合は、先に設定できる項目とその ID(設定項目 ID)を決めておくと良いと思います。

今回作成するウィジェットは下記の3つが設定できるようにしています。括弧内が設定項目 ID です。

  • 表示するタイトル(title)
  • 表示する記事の数(num)
  • 表示する順序(order)

 

下記は記事の一覧を表示するウィジェット(設定値あり)を作成するプログラムになります。

<?php
/**
 * Adds RecentPost_Widget widget.
 */
class RecentPost_Widget extends WP_Widget {

	/**
	 * ウィジェットの実体を作成
	 */
	public function __construct() {
		parent::__construct(
			'recent_post_widget', // Base ID.
			'自作の記事一覧', // Name.
			array( 'description' => '記事のリストを表示します' ) // Args.
		);
	}

	/**
	 * ウィジェットのフロントエンド表示
	 *
	 * @see WP_Widget::widget()
	 *
	 * @param array $args     ウィジェットの引数.
	 * @param array $instance データベースに保存されている設定値.
	 */
	public function widget( $args, $instance ) {
		/* ここからregister_sidebarに入力されたHTMLを出力 */

		/* before_widgetを出力 */
		echo $args['before_widget'];

		/* before_titleとafter_titleを出力 */
		if ( ! empty( $instance['title'] ) ) {
			/* タイトルが設定されている場合のみ出力 */
			echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ) . $args['after_title'];
		}

		/*
			ここから$instanceから設定値を取得
			まだ設定値が設定されていない場合はデフォルト値を設定
		*/

		/* 記事の表示数 */
		if ( ! empty( $instance['num'] ) ) {
			$num = intval( $instance['num'] );
		} else {
			/* 表示数が設定されていない場合は5を設定 */
			$num = 5;
		}

		/* 記事の表示順 */
		if ( ! empty( $instance['order'] ) ) {
			$order = $instance['order'];
		} else {
			/* 表示順が設定されていない場合は'DESC'(降順)を設定 */
			$order = 'DESC';
		}

		/* ここから記事一覧の表示 */

		/* サブクエリを作成 */
		$sub_args = array(
			'orderby'        => 'date',
			'order'          => $order,
			'posts_per_page' => $num,
		);

		/* データベースからデータ取得 */
		$my_query = new WP_Query( $sub_args );

		/* 記事のタイトルをリスト形式で表示 */
		echo '<ul>';
		while ( $my_query->have_posts() ) {
			$my_query->the_post();
			$page_title = get_the_title();
			echo '<li>' . $page_title . '</li>';
		}
		echo '</ul>';

		wp_reset_postdata();

		/* 最後にafter_widgetを出力 */
		echo $args['after_widget'];
	}

	/**
	 * バックエンドのウィジェットフォーム
	 *
	 * @see WP_Widget::form()
	 *
	 * @param array $instance データベースからの前回保存された値.
	 */
	public function form( $instance ) {
		/* 設定値が設定されていない時のデフォルト値設定 */
		if ( ! empty( $instance['title'] ) ) {
			$title = $instance['title'];
		} else {
			$title = '新しいタイトル';
		}

		if ( ! empty( $instance['num'] ) ) {
			$num = $instance['num'];
		} else {
			$num = '5';
		}

		if ( ! empty( $instance['order'] ) ) {
			$order = $instance['order'];
		} else {
			$order = 'DESC';
		}
		?>

		<!-- ウィジェットのタイトル設定フォームを表示 -->
		<p>
		<label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'タイトル:' ); ?></label>
		<input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>">
		</p>

		<!-- 記事の表示数設定フォームを表示 -->
		<p>
		<label for="<?php echo $this->get_field_id( 'num' ); ?>"><?php _e( '表示数:' ); ?></label>
		<input class="widefat" id="<?php echo $this->get_field_id( 'num' ); ?>" name="<?php echo $this->get_field_name( 'num' ); ?>" type="text" value="<?php echo esc_attr( $num ); ?>">
		</p>

		<!-- 記事の表示順設定フォームを表示 -->
		<p>
		<label for="<?php echo $this->get_field_id( 'order' ); ?>"><?php _e( '表示順:' ); ?></label>
		<input class="widefat" id="<?php echo $this->get_field_id( 'order' ); ?>" name="<?php echo $this->get_field_name( 'order' ); ?>" type="radio" value='DESC' checked='checked'>降順
		<input class="widefat" id="<?php echo $this->get_field_id( 'order' ); ?>" name="<?php echo $this->get_field_name( 'order' ); ?>" type="radio" value='ASC'>昇順
		</p>
		<?php
	}

	/**
	 * ウィジェットフォームの値を保存用にサニタイズ
	 *
	 * @see WP_Widget::update()
	 *
	 * @param array $new_instance 保存用にウィジェット設定フォームから送信された設定値.
	 * @param array $old_instance データベースからの以前保存された設定値.
	 *
	 * @return array 保存される更新された安全な値
	 */
	public function update( $new_instance, $old_instance ) {
		/* サニタイズ後の設定値を格納するための$instanceを作成 */
		$instance = array();

		/*
		 * instance['title']:タイトル
		 * instance['num']:表示数
		 * instance['order']:表示順
		 */

		/* タイトルのサニタイズ */
		if ( ! empty( $new_instance['title'] ) ) {
			/*
				フォームに設定された文字列が空でない場合は
				strip_tagsを実行後の文字列をタイトルの設定値に設定
			*/
			$instance['title'] = strip_tags( $new_instance['title'] );
		} else {
			/* 空の場合は「新しいタイトル」をタイトルに設定 */
			$instance['title'] = '新しいタイトル';
		}

		/* 表示数のサニタイズ */
		if ( ! empty( $new_instance['num'] ) ) {
			/* フォームに設定された文字列が空でない場合 */
			if ( intval( strip_tags( $new_instance['num'] ) ) > 0 ) {
				/* 文字列をint化した数値が0より大きい場合のみ、その文字列を表示数として設定 */
				$instance['num'] = strip_tags( $new_instance['num'] );
			} else {
				/* 0より小さい場合はデフォルト値5を設定 */
				$instance['num'] = '5';
			}
		} else {
			/* フォームに設定された文字列が空の場合はデフォルトの5を設定 */
			$instance['num'] = '5';
		}

		/* 表示数順序のサニタイズ */
		if ( ! empty( $new_instance['order'] ) ) {
			/* フォームに設定された文字列が空でない場合 */
			if ( strip_tags( $new_instance['order'] ) == 'DESC'
				|| strip_tags( $new_instance['order'] ) == 'ASC' ) {
				/* 設定された値が'DESC'もしくは'ASC'であれば新しい設定値として反映 */
				$instance['order'] = strip_tags( $new_instance['order'] );
			} else {
				/* 設定値がおかしい場合はデフォルト値'DESC'を設定 */
				$instance['order'] = 'DESC';
			}
		} else {
			/* フォームに設定された文字列が空の場合はデフォルトの'DESC'を設定 */
			$instance['order'] = 'DESC';
		}

		return $instance;
	}

}

/**
 * ウィジェット作成関数
 */
function register_my_widgets() {
	register_widget( 'RecentPost_Widget' );
}

add_action( 'widgets_init', 'register_my_widgets' );
?>

上記を function.php に記述すれば、ウィジェット設定画面では作成した「自作の記事一覧」の設定を行うことができ、

設定値を持つウィジェットの設定フォームの例

ウィジェットを表示すると、設定した値に応じて記事の表示順や記事の表示数が変化していることが確認できると思います。

ウィジェットの設定変更が反映される様子

プログラムの詳細についてはプログラムおよびプログラム内のコメントを参照していただければと思います。ポイントのみをここでは説明していきます。

__construct メソッド

自作ウィジェット1の __construct メソッドと全く同じになります。

widget メソッド

自作ウィジェット1の時と異なるのは下記の点です。

  • $instance の値に基づいてサブクエリを作成している

$instance はウィジェットの設定値(設定フォームで設定され、update メソッドにより反映される値)が格納される配列です。ですので、$instance の値に応じて表示する内容を変更するような widget メソッドを作成すれば、設定フォームで設定された設定値に基づいて表示する内容をが変わるウィジェットを作成することが可能です。

$instance は配列であり、キー名が設定項目 ID、格納される値がその設定項目の設定値となります。つまり $instance[‘設定項目 ID’] に、その設定項目に対する設定値が格納されています。

具体的には上記のプログラムの場合は、$instance は title と num と order という設定項目 ID を持ち、下記のような設定値を保持しています。

  • $instance[‘title’]:表示するタイトル
  • $instance[‘num’]:記事の表示数
  • $instance[‘order’]:記事の表示順序

$instance[‘title’] の値は下記で参照しています。apply_filters 関数の引数として使用していますが、要は $instance[‘title’] はウィジェットのタイトルして表示しています。ですので設定フォームでタイトルを変更すれば、ウィジェットのタイトルを変更することが可能です。

/* before_titleとafter_titleを出力 */
if ( ! empty( $instance['title'] ) ) {
	/* タイトルが設定されている場合のみ出力 */
	echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ). $args['after_title'];
}

$instance[‘num’] と $instance[‘order’] は下記で参照しており、最終的にサブクエリの設定値として使用されます。ですので設定フォームでタイトルを変更すれば、ウィジェットに表示する記事一覧の表示数と表示順を変えることが可能です。

/* 記事の表示数 */
if ( ! empty( $instance['num'] ) ) {
	$num = intval( $instance['num'] );
} else {
	/* 表示数が設定されていない場合は5を設定 */
	$num = 5;
}

/* 記事の表示順 */
if ( ! empty( $instance['order'] ) ) {
	$order = $instance['order'];
} else {
	/* 表示順が設定されていない場合は'DESC'(降順)を設定 */
	$order = 'DESC';
}

/* ここから記事一覧の表示 */

/* サブクエリを作成 */
$sub_args = Array(
	'orderby' => 'date',
	'order' => $order,
	'posts_per_page' => $num,
 );

/* データベースからデータ取得 */
$my_query = new WP_Query( $sub_args );

ポイントは $instance[‘設定項目 ID’] に設定値が格納されていない場合のケアです。設定フォームで設定を行うまでは設定値が格納されません。ですので最初の1度目の起動時は $instance[‘設定項目 ID’] は空です。

この状態で $instance[‘設定項目 ID’] に格納される設定値をそのまま用いて widget で処理を行ってしまうと、表示がおかしくなる or エラーになる場合があります。

そのため、必ず $instance[‘設定項目 ID’] が空であるかどうかを判断し、空の場合はデフォルトの値を設定して処理を行うようにプログラムを記述した方が良いです。

form メソッド

form メソッドで主に行うことは下記です。

  • ユーザーから設定を受け付ける入力フォームを作成する

重要なポイントは、後述する update メソッドの引数となる $new_instance に格納されるように入力フォームを作成する必要がある点です。

上記のプログラムでは、表示タイトルと記事の表示数、表示する順序を設定できるフォームを表示できるように form メソッドを作成しています。

例えば表示タイトルの設定を受け付けるフォームを表示しているのは下記部分になります。

<!-- ウィジェットのタイトル設定フォームを表示 -->
<p>
<label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'タイトル:' ); ?></label>
<input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>">
</p>

これにより設定フォームが表示され、表示タイトルの設定が受け付けられるようになります。

一番重要なのは、input タグの name 属性です。name 属性は下記のように指定します。

name="<?php echo $this->get_field_name( '設定項目 ID' ); ?>

特にこの name 属性の「設定項目 ID」部分が重要です。

フォームで受け付けた設定値は、後述する update メソッドの引数の $new_instance として渡されます。その $new_instance は配列であり、上記の「設定項目 ID」がキーとなり、フォームに入力された値(文字列なども)が配列に格納される値となります。

例えば name 属性を下記のように設定した場合、

name="<?php echo $this->get_field_name( 'test' ); ?>

$new_instance[‘test’] にフォームに入力された値が格納された状態で、update メソッドに $new_instance が渡されることになります。

てきとうに name 属性を設定してしまうと、update メソッドに設定値が上手く渡せませんので注意しましょう!

update メソッド

update メソッドの引数は下記の2つになります。

  • $new_instance:新しい設定値が格納された配列
  • $old_instance:古い設定値が格納された配列

$new_instance には、form メソッドで生成する入力フォームに指定された設定値が格納されます。前述の通り、入力フォーム(例えば input タグで生成される入力フォーム)の name 属性を下記のように指定した場合、この入力フォームで指定された設定値は $new_instance 配列の「設定項目 ID」をキーとした要素として値が格納されています。

name="<?php echo $this->get_field_name( '設定項目 ID' ); ?>

$old_instance にはウィジェットの以前の設定値が格納されています。こちらも $new_instance 同様に「設定項目 ID」をキーする配列となります。

この2つの配列を用いて、update メソッドでは主に下記の2つのことを行います。

  • $new_instance に格納される設定値をサニタイズする
  • サニタイズ後の設定値をウィジェットの設定に反映する

サニタイズとは、設定値を無害化することです。

例えば文字列を受け付ける入力フォームの場合、ユーザーが HTML タグなどを入力する場合があります。このような場合、文字列をそのままウィジェットに表示すると、ウィジェットやページの表示が崩れたものになる・自分の意図したものにならない、などの問題が発生することがあります。

また数値を設定すべき入力フォームに、数値以外のデータが入力されると、そのデータを用いてウィジェット表示してしまうとエラーが発生する場合もあります。

こういった問題を未然に防ぐために、ユーザーが入力した設定値が問題ないかどうかを判断し、問題ある場合は問題ない設定値に置き換える処理がサニタイズであり、ウィジェットを安全に表示するために update メソッドの中で行うべき処理の一つとなります。

例えば下記は、記事の表示数の設定値をサニタイズする処理になります。$instance にサニタイズ後の設定値を格納するようにしています。

/* 表示数のサニタイズ */
if( ! empty( $new_instance['num'] )) {
	/* フォームに設定された文字列が空でない場合 */
	if( intval( strip_tags( $new_instance['num'] ) ) > 0) {
		/* 文字列をint化した数値が0より大きい場合のみ、その文字列を表示数として設定 */
		$instance['num'] = strip_tags( $new_instance['num'] );
	} else {
		/* 0より小さい場合はデフォルト値5を設定 */
		$instance['num'] = '5';
	}
} else {
	/* フォームに設定された文字列が空の場合はデフォルトの5を設定 */
	$instance['num'] = '5';
}

記事の表示数の新しい設定値である $new_instance[‘num’] が空 or 数値に変換した結果が0以下の場合は、デフォルト設定値の ‘5’ を新たな設定値とするようにサニタイズしています。ここではデフォルト設定値の ‘5’ を用いていますが、以前の設定値である $old_instance[‘num’] を新たな設定値として用いるのも良いと思います。

2つ目の処理の「サニタイズ後の設定値をウィジェットの設定に反映する」は、サニタイズ後の設定値を格納した配列を戻り値として return することで実現することができます。

上記のプログラムではサニタイズ後の設定値を $instance に格納するようにしていますので、この $instance を update メソッドの戻り値とすることでサニタイズ後の設定値をウィジェットの設定に反映しています。

まとめ

このページでは、ワードプレスのウィジェットを自作する方法について解説しました。

ポイントは WP_Widget クラスのサブクラスを作成し、4つのメソッドをオーバーライドする点だと思います。変更するのがこの4つのメソッドだけなので、割と簡単にウィジェットを自作することができます。

ウィジェットはユーザーがソースコード変更なしに簡単にテーマをカスタマイズできる非常に便利な機能です。是非ウィジェットを作成し、より使いやすいテーマを開発していきましょう!

コメントを残す

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

ワードプレスの処理時間は約 0.739 秒です