WEB

これだけ!?WordPressのWidget(ウィジェット)の作り方

これだけ!?WordPressのWidget(ウィジェット)の作り方

こんにちは、エンジニアの王です。今日はWordPressの「Wiget(ウィジェット)」を自作する方法について紹介したいと思います。

Widgetとは

‘Widget’ とは「小さな部品」という意味です。WordPressでよくWidgetが使われる場面には、サイドバーの「カレンダー」、「アーカイブ」、「検索」などがありますね。
ただ、これらの部品は別にWidgetを使わなくても、コードを書けば実現できるわけです。では、どうしてわざわざWidgetにするのでしょうか。

Widgetにするメリット

Widgetにする主なメリットは、以下のとおりになります。

  • Widgetごとに設定項目を持たせることができる
    • 設定を変えるためにソースコードを書き直す必要がなくなる
    • 一般ユーザでも簡単に設定できる
    • 取り外しを管理画面でおこなうことができる
  • 再利用可能
    • 管理画面上で、同じWidgetを違う「サイドバー」に設置できる

ひと言で言えば、「ユーザビリティが上がる」ということになります。

以下の図は、WordPressのデフォルトのテーマでWidgetを使った様子です。
右はWidgetの管理画面で、左は実際の表側の表示です。わかりやすい!

p1

Widgetを自作する

それではいよいよ、Widgetを自作していきましょう。まずは説明用に、簡単なWidgetを作成してみます。

▼管理画面

p2

▼表側での表示

p3

以下は、functions.phpに記述するコードです。

class My_Widget extends WP_Widget{
	/**
	 * Widgetを登録する
	 */
	function __construct() {
		parent::__construct(
			'my_widget', // Base ID
			'Widgetの名前', // Name
			array( 'description' => 'Widgetの説明', ) // Args
		);
	}

	/**
	 * 表側の Widget を出力する
	 *
	 * @param array $args      'register_sidebar'で設定した「before_title, after_title, before_widget, after_widget」が入る
	 * @param array $instance  Widgetの設定項目
	 */
	public function widget( $args, $instance ) {
        $email = $instance['email'];
		echo $args['before_widget'];

        echo "<p>Email: ${email}</p>";

        echo $args['after_widget'];
	}

    /** Widget管理画面を出力する
     *
     * @param array $instance 設定項目
     * @return string|void
     */
    public function form( $instance ){
        $email = $instance['email'];
        $email_name = $this->get_field_name('email');
        $email_id = $this->get_field_id('email');
        ?>
        <p>
            <label for="<?php echo $email_id; ?>">Email:</label>
            <input class="widefat" id="<?php echo $email_id; ?>" name="<?php echo $email_name; ?>" type="text" value="<?php echo esc_attr( $email ); ?>">
        </p>
        <?php
    }

    /** 新しい設定データが適切なデータかどうかをチェックする。
     * 必ず$instanceを返す。さもなければ設定データは保存(更新)されない。
     *
     * @param array $new_instance  form()から入力された新しい設定データ
     * @param array $old_instance  前回の設定データ
     * @return array               保存(更新)する設定データ。falseを返すと更新しない。
     */
    function update($new_instance, $old_instance) {
        if(!filter_var($new_instance['email'],FILTER_VALIDATE_EMAIL)){
            return false;
        }
        return $new_instance;
    }
}

add_action( 'widgets_init', function () {
	register_widget( 'My_Widget' );  //WidgetをWordPressに登録する
	register_sidebar( array(  //「サイドバー」を登録する
		'name'          => 'サイドバー(上部)',
		'id'            => 'my_sidebar',
		'before_widget' => '<div>',
		'after_widget'  => '</div>',
		'before_title'  => '',
		'after_title'   => '',
	) );
} );

出力したいテンプレートファイル(sidebar.phpなど)でWidgetを出力するためには、以下を記述します。

<?php if ( is_active_sidebar( 'my_sidebar' ) ) : ?>
    <div>
        <?php dynamic_sidebar( 'my_sidebar' ); ?>
    </div><!-- #primary-sidebar -->
<?php endif; ?>

 

なんと、たったこれだけで完了なんです。以下、順に見ていくことにしましょう。

まず、Widgetを作るには、WordPressの WP_Widget クラスを継承して、サブクラスで以下の4つのメソッドをオーバーライドします。

  • __construct (ベースIDやWidgetの表示名を設定する)
  • widget (表側の Widget を出力するメソッド)
  • form (管理画面でのフォームを出力するメソッド)
  • update (オプションです。バリデーションをかけるメソッド)

さきほどの図で説明すると、以下のようになります。

p4

サブクラスができたらwidgets_initにフックして、register_widgetでWidgetをWordPressに登録します。

Widgetは必ず「サイドバー」に入れて使うものなので、必要であればregister_sidebarで新しい「サイドバー」を用意してあげましょう。そして表側で出力するときに「サイドバー」を出力すれば、中に入れてあるWidgetをまとめて出力できるようになります。

今回の例では、サイドバーのidをmy_sidebarにしているので、dynamic_sidebar( 'my_sidebar' )によって出力されているのが確認いただけたと思います。

基本的なことについては以上です。

注意してほしいのは、form()の中ではinputやtextareaなど、name属性の値は必ず $this->get_field_name() を使って出力する、ということ。そうしておかないと、データベースに保存されません。

Tips

表側を表示するメソッドであるwidgetでは、設定が入ってる配列($instance)が渡されるのですが、もしAjaxを利用したWidgetを想定しているのなら、ひょっとしたらHTML上に書き出したくない情報(E-mailとか、パスワードとか)があるかもしれません。
そういった場合は$wpdbを利用して、データベースから直接設定を引っ張ってくるといいでしょう。

global $wpdb;
$option_name = 'widget_' . $this->id_base;
$query = "SELECT option_value FROM $wpdb->options WHERE option_name = '${option_name}'";
$option = unserialize($wpdb->get_var($query))[2];

また、管理画面でjsの制御が必要となる場面も多々あると思いますので、__constructの中でjsを登録することもよくあります。

add_action( 'admin_enqueue_scripts', function($hook) {
	if($hook==='widgets.php'){ //「ウィジェット」画面以外は登録しない
		wp_register_script( 'my_script', get_template_directory_uri() . '/js/my_script.js' );
		wp_enqueue_script( 'my_script', get_template_directory_uri() . '/js/my_script.js', array('jquery'), null, true );
	}
} );

まとめ

以上、簡単ではありますが、WordPressのWidget(ウィジェット)を自作する方法について解説させていただきました。

皆さんも、ぜひいろいろと試してみてください!


LIGでは、エンジニアを絶賛募集中!
http://liginc.co.jp/recruit/mid_career

この記事を書いた人

王
バックエンドエンジニア 2012年入社
LIGの王です。ウェブの全てを学ぶ為、中国は四川省より日本にやってきました。王という名に恥じぬよう、ウェブ業界のKINGとなるべく日々頑張っております。よろしくお願いいたします。