外観 > ウィジェットには、デフォルトで様々なウィジェットが用意されてますよね。このウィジェットって、実は自分で作成することができます。

当記事では、テーマ独自のウィジェットを作成する方法について解説していきます。

なお、ウィジェットを自作するためには、ウィジェットエリアを登録しておく必要があります。まだ、ウィジェットエリアの登録がお済みでない方は、以下の記事を参考に登録を済ませてください。

なお、このオリジナルウィジェットは、クラシックテーマ開発向けの内容になります。

ウィジェットは「WP_Widget」を継承して作成する

WordPressには、ウィジェットを作成するための基本クラス「WP_Widget」が定義されています。既存のウィジェットは、このクラスを拡張して作られているんですね。

class WP_Widget

例えば、「カテゴリーウィジェット」を定義しているクラス(WP_Widget_Categories)を見てみると、以下のように「WP_Widget」を継承して作られています。

class WP_Widget_Categories extends WP_Widget {
︙
}

オリジナルウィジェットも同様の方法で自作できるようになっています。

オリジナルウィジェットの自作方法

今回作成するのは、ウィジェットで入力したテキストを保存してサイト上に表示する基本的なものです。以下のステップで作成していきますので、順番にfunctions.phpに記入していきましょう。

  1. オリジナルウィジェット用クラスの作成
  2. コンストラクタを定義
  3. 作成したオリジナルウィジェットの登録
  4. ウィジェットの設定フォームの作成
  5. 保存時のデータの無害化
  6. サイト上に出力

オリジナルウィジェット用クラスの作成

まずは、オリジナルウィジェットのクラス名を決めます。今回は「MY_Original_Widget」という名称で進めていきますが、自由に決めていただいて構いません。

PHPのクラス継承は、通常のクラス定義の後に「extends 継承するクラス名」のような形で行います。

// クラスの基本的な継承方法
class 作成するクラス名 extends 継承するクラス名 {
}

// WP_Widgetを継承して、MY_Original_Widgetクラスを作成
class MY_Original_Widget extends WP_Widget {
  // この中にその他の記述を追加していく
}

これで「MY_Original_Widget」クラスを作成することができました。

コンストラクタを定義

次に「MY_Original_Widget」クラスのコンストラクタを定義していきます。コンストラクタは、クラスを初期化した時に実行されるメソッドです。

このコンストラクタ内では、以下のようにウィジェットのIDや名前、説明文を定義してあげます。

// コンストラクタを定義
public function __construct() {
  parent::__construct(
    'my_original_widget', // ウィジェットのID
    '【オリジナル】ウィジェット名', // ウィジェットの名称(管理画面で表示される)
    array(
      'description' => 'ウィジェットの説明文', // ウィジェットの説明(管理画面で表示される)
    )
  );
}

コメントアウトを入れている3箇所を適宜変えていただければ、その他のウィジェットでもお使いいただけます。

作成したオリジナルウィジェットの登録

クラスを定義しただけでは、管理画面にもサイト上にもウィジェットは表示されません。「外観 > ウィジェット」に反映させるため、ウィジェットの登録を行います。

登録方法は簡単で「register_widget()」の引数にウィジェットクラス名を指定するだけです。この関数は「widgets_init」フックで実行しましょう。

// オリジナルウィジェット「MY_Original_Widget」の登録
add_action( 'widgets_init', function(){
  register_widget( 'MY_Original_Widget' );
} );

なお、ウィジェット登録を行うと「外観 > ウィジェット」にアイテムが追加され、操作できるようになります。

独自ウィジェットの追加

ウィジェットの設定フォームの作成

作成したウィジェットを管理画面で確認できるようになったので、設定フォームを作成していきます。フォーム出力には「form()」メソッドを利用します。

今回はタイトルの入力項目を作成していきます。以下はタイトルを入力するテキストフィールドのサンプルですので「MY_Original_Widget」クラス内にコピペしてみてください。

<?php
// form出力
public function form( $instance ) {
  $instance = wp_parse_args(
    (array) $instance,
    array(
      'title' => '', // 初期値をココに入力
    )
  );
?>
<p>
  <label for="<?php echo $this->get_field_id( 'title' ); ?>">タイトル</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( $instance['title'] ); ?>" />
</p>
<?php
}

上記で使われている変数やメソッドについては、以下に紹介します。

$instance ウィジェットの設定値が格納されている
wp_parse_args() 引数の配列とデフォルト値の配列を結合する
get_field_id() フィールドのIDを取得
get_field_name() フィールドのname属性を取得

これで以下のように設定フォームが表示されるようになったはずです。

ウィジェットの設定フォーム

保存時のデータの無害化

ウィジェットの設定を保存する際、より安全なデータにするために無害化を行います。保存時の処理は「update()」メソッドを利用します。

以下は、入力したタイトルを保存する際に改行や空白、HTMLタグを除去して保存するサンプルになります。

// データ保存時の処理
public function update( $new_instance, $old_instance ) {
  $instance = $old_instance;
  $instance['title'] = sanitize_text_field( $new_instance['title'] );
  return $instance;
}

上記で使われている変数やメソッドについては、以下に紹介します。

$new_instance 送信されたデータ
$old_instance もともと保存されているデータ
sanitize_text_field() 改行や空白、HTMLタグの除去を行う

これで設定フォームにHTMLタグ込みのテキストを入力してみてください。保存直後に削除されるようになったはずです。

サイト上に出力

サイト上に表示されるウィジェットの中身を作成していきましょう。サイトに表示するコンテンツの作成は「widget()」メソッドを利用します。

このメソッド内に記述した内容がフロントに反映されます。なお、設定したデータは、第二引数の「$instance」の中に格納されています。

// ウィジェットの出力
public function widget( $args, $instance ) {
  echo $args['before_widget'];
  if ( $instance['title'] ) {
    echo $args['before_title'] . $instance['title'] . $args['after_title'];
  }
  
  // ココに表示したい内容を入力
  
  echo $args['after_widget'];
}

なお、上記の「$args」の中身は「register_sidebar()」でウィジェットエリアを登録した時に定義したものです。そちらをオリジナルウィジェットで利用する必要がなければ、書かなくても大丈夫です。

オリジナルウィジェットの完成形

コピペしたのに何故か動かないなという方は、記入する場所を間違っているかもしれません。以下に今回ご紹介した記述をまとめましたので、再度ご確認ください。

<?php
/* オリジナルウィジェット「MY_Original_Widget」の登録 */
add_action( 'widgets_init', function(){
  register_widget( 'MY_Original_Widget' );
} );

/* WP_Widgetを継承して、MY_Original_Widgetクラスを作成 */
class MY_Original_Widget extends WP_Widget {

  /* コンストラクタを定義 */
  public function __construct() {
    parent::__construct(
      'my_original_widget', /* ウィジェットのID */
      '【オリジナル】ウィジェット名', /* ウィジェットの名称(管理画面で表示される)*/
      array(
        'description' => 'ウィジェットの説明文', /* ウィジェットの説明(管理画面で表示される)*/
      )
    );
  }

  /* form出力 */
  public function form( $instance ) {
    $instance = wp_parse_args(
      (array) $instance,
      array(
        'title' => '', /* 初期値をココに入力 */
      )
    );
?>
<p>
  <label for="<?php echo $this->get_field_id( 'title' ); ?>">タイトル</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( $instance['title'] ); ?>" />
</p>
<?php
  }

  /* データ保存時の処理 */
  public function update( $new_instance, $old_instance ) {
    $instance = $old_instance;
    $instance['title'] = sanitize_text_field( $new_instance['title'] );
    return $instance;
  }

  /* ウィジェットの出力 */
  public function widget( $args, $instance ) {
    echo $args['before_widget'];
    if ( $instance['title'] ) {
      echo $args['before_title'] . $instance['title'] . $args['after_title'];
    }
  
    /* ココに表示したい内容を入力 */
  
    echo $args['after_widget'];
  }

}

まとめ

今回は、オリジナルウィジェットを自作する手順についてご紹介しました。この方法で既存テーマにも独自のウィジェットを追加できるので、ぜひお試しください。

なお、一般的にウィジェットを表示するサイドバーの自作方法についてもご紹介してますので、こちらも合わせてご覧ください。