2017年4月10日追記:
ウィジェット作成について、より詳細なページを作成しました。
WordPressのウィジェットを自作する必要になったので色々調べた所、最低限の基本形が分かったのでメモです。
目次
ウィジェット作成に必要な最低限の記述
ウィジェットを自作するときの最低限の記述は以下です。WordPressが用意しているウィジェット用のクラスを継承して作成します。
class My_Widget extends WP_Widget {
function __construct() {
//コンストラクタ。初期化処理
$widget_ops = array('description' => 'ウィジェットの説明文です。');
parent::__construct(
false, //ウィジェットのIDに任意の名前を設定したければ文字列を指定
'僕のウィジェット', //ウィジェットのタイトル
$widget_ops
);
}
function widget($args, $instance) {
// ウィジェットの表示処理を記述
}
function update($new_instance, $old_instance) {
// ウィジェットの設定の更新処理を記述。主にセキュリティを考えたサニタイズ用
return $new_instance;
}
function form($instance) {
// ウィジェットの設定用フォームを記述
}
}
add_action('widgets_init',create_function('', 'return register_widget("My_Widget");'));
このソースコードを有効化しているWordPressテーマのfunctions.phpや自前のプラグインに貼り付けると、取り敢えず「外観 > ウィジェット」の一覧に「僕のウィジェット」という名前のウィジェットが現れます。
もちろん表示処理用の関数であるwidget()
に記述をしていないので、このままでは有効化してもホームページには何も表示されません。
クラス「WP_Widget」について
継承元の親クラス「WP_Widget」はwp-includes/class-wp-widget.php
ファイルで定義されています。ここで定義されているコンストラクタと3つの主要関数を、自作の子クラス「My_Widget」でオーバーライドします。
WordPressで最初から実装されてる各ウィジェット(「カレンダー」や「最新の投稿」など)も、このWP_Widgetクラスを継承して作られています。
コンストラクタについて
PHPのドキュメントには以下のように記述されています。
PHP 5.3.3 以降、名前空間つきのクラス名の最後の部分と同じ名前のメソッドは コンストラクタとみなされなくなりました。 名前空間を使っていないクラスは今までと変わりません。
PHP: コンストラクタとデストラクタ – Manual
調べが甘く深くはまだ分からないのですが、他のプログラム言語のようにクラス名と同じ関数を記述して「これコンストラクタね!」とするのは今後控えた方が良いようです。なのでコンストラクタは予約された共通名のコンストラクタ__construct()
を使うことに。
ちなみにコンストラクタとは初期化処理専用の関数です。わざわざ初期化処理用の自作関数を用意して
$myWidget->init();
と記述しなくても、コンストラクタはインスタンス生成時に自動的に実行されるので初期化処理のし忘れを防げます。詳しくはこちらが参考になります。
その他関数について
11行目: widget($args, $instance)
ウィジェットの表示処理を記述する関数です。
引数の$args
にはウィジェットの情報が渡されます。ダンプすると分かりますが、ウィジェットのタイトルやラッパー用タグが連想配列で入ってます(register_sidebar()
関数に渡す引数がまさにコレです)。これらを必要に応じて出力します。
$instance
にはform()
関数で出力した設定用フォームに入力された値が入ります。form()
関数で何もフォームを出力せず、ウィジェットの管理画面から設定が保存されなければ中身はNULL(空)です。
14行目: update($new_instance, $old_instance)
ウィジェットの保存された新しい設定値を既に設定された値と比較したり、サニタイズしたりするための関数です。
$new_instance
には新しい設定値が、$old_instance
には既に設定された古い値が入ります。サニタイズは$new_instance
に対して行います。
17行目: form($instance)
管理画面の「外観 > ウィジェット」でウィジェットを有効化した時に表示される、設定フォームを出力するための関数です。
引数の$instance
には現在の設定値が渡されます。
基本形を少しだけ発展させる
上記の基本形のソースコードはあまりにも最低限なので、少し発展させてみます。
管理画面のウィジェットからタイトルを設定し、それを出力する処理を追加します。
class My_Widget extends WP_Widget {
function __construct() {
$widget_ops = array('description' => 'ウィジェットの説明文です。');
parent::__construct(
false,
'僕のウィジェット',
$widget_ops
);
}
function widget( $args, $instance ) {
// ウィジェットの表示処理を記述
extract($args); //連想配列に含まれるキーを変数名、値をその変数の値として新しい変数を作成
$title = apply_filters( 'widget_title', empty( $instance['title'] ) ? '' : $instance['title'], $instance, $this->id_base );
echo $before_widget;
if ( !empty( $title ) ) { echo $before_title . $title . $after_title; } ?>
<div class="widgetContent">ウィジェットの中身です。</div>
<?php
echo $after_widget;
}
function update( $new_instance, $old_instance ) {
// ウィジェットの設定の更新処理を記述。主にセキュリティを考えたサニタイズ用
$instance = $old_instance;
$instance['title'] = strip_tags($new_instance['title']); //不要なNULL、HTMLタグ、PHPソースコードを排除
return $instance;
}
function form( $instance ) {
// ウィジェットの設定用フォームを記述
$instance = wp_parse_args( (array) $instance, array( 'title' => '', 'text' => '' ) ); //クエリーとデフォルト値のマージ(合併)
$title = strip_tags($instance['title']); //タイトルを取得
?>
<p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('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($title); ?>" /></p>
<?php
}
}
add_action('widgets_init',create_function('', 'return register_widget("My_Widget");'));
参考になった(というよりもほぼコピーした)のはWordPress標準のテキストウィジェットです。テキストウィジェットのソースコードはwp-includes/widgets/class-wp-widget-text.phpで定義されてます。
やはり処理の流れは、28行目以降のform()
関数で設定用フォームの出力をし、update()
関数でサニタイズし(23行目)、10行目以降のwidget()
関数で出力処理をしています。
注意点として、フォーム要素のIDや名前を生成する関数は専用のget_field_id()
やget_field_name()
を使用するようにしてください。(33行目、34行目の「label」や「input」の属性で使用しているので参考にしてみてください)
長々となってしまいましたが、ウィジェット作成の基本形はこのような内容になります。