WordPressでウィジェットを作るカスタマイズ

WordPressでウィジェットを作るカスタマイズ

Posted at December 10,2010 2:55 AM
Tag:[Widget, WordPress]

WordPress 3のサイドバーにウィジェットを表示するカスタマイズ」の続きで、WordPress 3でウィジェットを作るカスタマイズを紹介します。

1.基本

ウィジェット作成に必要なソースコードは次のようなイメージです。

class WP_Widget_xxx extends WP_Widget {
    function WP_Widget_xxx() { }
    function form( $instance ) { }
    function update( $new_instance, $old_instance ) { }
    function widget( $args, $instance ) { }
}
function WP_Widget_xxxInit() {
    register_widget('WP_Widget_xxx');
}
add_action('widgets_init', 'WP_Widget_xxxInit');

ソースコードをテーマのfunction.php、あるいはプラグインファイルに記述すれば、ウィジェットが追加される仕組みになっています。

前述のソースコードは3つの部分に大別されます。

  1. WP_Widgetを継承したクラスWP_Widget_xxxの定義
  2. ウィジェット登録する関数(WP_Widget_xxxInit)の定義
  3. add_action()を使って、ウィジェット管理画面を初期化するフックポイントwidgets_initにウィジェット初期化関数(WP_Widget_xxxInit())の登録

処理は3→2→1の順で実行されます。2と3はxxxの部分を任意の名称にするだけでどんなウィジェットにも使いまわせます。3を次のように書けば2を省略できます。

add_action('widgets_init', create_function('', 'return register_widget("WP_Widget_xxx");'));

実際にウィジェットの中身を作るのは1のクラスWP_Widget_xxxで、クラス内で定義する関数は次の4つです。

  • コンストラクタ(WP_Widget_xxx)
  • form():管理画面のウィジェットにフォームを表示する関数
  • update():管理画面のウィジェットの「保存」をクリックしたときに実行される関数
  • widget():ウィジェットを表示する関数

ここではデフォルトのカレンダーウィジェットを例に、それぞれの関数の動作について解説します。

カレンダーウィジェット
カレンダーウィジェット

ウィジェットで表示されたカレンダー
ウィジェットで表示されたカレンダー

カレンダーウィジェットのソースコード

class WP_Widget_Calendar extends WP_Widget {
 
    function WP_Widget_Calendar() {
        $widget_ops = array('classname'   => 'widget_calendar',
                            'description' => __( 'A calendar of your site’s posts') );
        $this->WP_Widget('calendar', __('Calendar'), $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 ( $title )
            echo $before_title . $title . $after_title;
        echo '<div id="calendar_wrap">';
        get_calendar();
        echo '</div>';
        echo $after_widget;
    }
 
    function update( $new_instance, $old_instance ) {
        $instance = $old_instance;
        $instance['title'] = strip_tags($new_instance['title']);
        return $instance;
    }
 
    function form( $instance ) {
        $instance = wp_parse_args( (array) $instance, array( 'title' => '' ) );
        $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
    }
}
 
function WP_Widget_CalendarInit() {
    register_widget('WP_Widget_Calendar');
}
 
add_action('widgets_init', 'WP_Widget_CalendarInit');

1.コンストラクタ

コンストラクタはウィジェット名の定義、ウィジェットの登録などを行います。カレンダーウィジェットのコンストラクタは次のようになっています。

function WP_Widget_Calendar() {
    $widget_ops = array('classname'   => 'widget_calendar',
                        'description' => __( 'A calendar of your site&#8217;s posts') );
    $this->WP_Widget('calendar', __('Calendar'), $widget_ops);
}

WP_Widget()の引数の意味は次の通りです。

WP_Widget(ウィジェットID, ウィジェット名, ウィジェットオプション, コントロールオプション);

ウィジェットIDは任意の小文字の文字列、ウィジェット名は管理画面のウィジェットタイトルになります。

ウィジェットオプションにはハッシュclassnameとdescriptionを配列で定義でき、descriptionはウィジェットタイトル下の説明文になります。

コントロールオプションには、ウィジェットのサイズを定義するハッシュwidthとheightを配列で定義できます(有効なのはwidthのみの模様)。

$control_ops = array('width' => '300px', 'height' => '300px');

2.form()

form()はウィジェット管理画面のフォームを定義します。フォームを定義することでウィジェットの表示をカスタマイズすることができます。

以下はカレンダーウィジェットのタイトル名を変更するためのフォームです。

function form( $instance ) {
    $instance = wp_parse_args( (array) $instance, array( 'title' => '' ) );
    $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
}

関数の引数$instanceにはフォームデータが設定されており、1行目のwp_parse_argsで$instanceをハッシュ形式に変換します。

$instance = wp_parse_args( (array) $instance, array( 'title' => '' ) );

2行目で、ハッシュキーtitleの値から不要なタグを除去します。

$title = strip_tags($instance['title']);

残りの処理で、取得したフォームデータ($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>

関数get_field_id()とget_field_name()は上記の処理を流用すれば良いと思います。

参考までに、get_field_id()はwp-includes/widgets.phpにあり、次の処理を行っています。

function get_field_id($field_name) {
    return 'widget-' . $this->id_base . '-' . $this->number . '-' . $field_name;
}

get_field_name()もwp-includes/widgets.phpにあり、次の処理を行っています。

function get_field_name($field_name) {
    return 'widget-' . $this->id_base . '[' . $this->number . '][' . $field_name . ']';
}

3.update()

update()は、管理画面のウィジェットの「保存」をクリックしたときに実行し、フォームデータを保存します。

function update( $new_instance, $old_instance ) {
    $instance = $old_instance;
    $instance['title'] = strip_tags($new_instance['title']);
    return $instance;
}

関数の引数$new_instanceは変更後のデータ、$old_instanceは変更前のデータが設定されています。ここでは2行目でハッシュキーtitleの値のみ取り出して返却していますが、単純に次のようにしてもよいでしょう。

function update( $new_instance, $old_instance ) {
    return $new_instance;
}

4.widget()

widget()はウィジェットを表示する役割があります。前述のようなフォームデータがある場合、この関数でフォームデータの値を取得し、ウィジェットの表示に反映させます。

function widget( $args, $instance ) {
    extract($args);
    $title = apply_filters('widget_title', empty($instance['title']) ?
                   '&nbsp;' : $instance['title'], $instance, $this->id_base);
    echo $before_widget;
    if ( $title )
        echo $before_title . $title . $after_title;
    echo '<div id="calendar_wrap">';
    get_calendar();
    echo '</div>';
    echo $after_widget;
}

関数の引数$instanceは、form()の引数と同様、フォームデータです。

1行目のextractで、引数$argsの内容を配列にセットします(ここでは使っていない模様)。

extract($args);

2行目でフィルターフックwidget_titleを実行して、フォームのtitleのデータを変数$titleに設定します。

$title = apply_filters('widget_title', empty($instance['title']) ?
                   '&nbsp;' : $instance['title'], $instance, $this->id_base);

残りの処理でカレンダーを表示します。関数get_calendarは外部の関数でカレンダーデータを取得します(ここでは割愛)。

echo $before_widget;
if ( $title )
    echo $before_title . $title . $after_title;
echo '<div id="calendar_wrap">';
get_calendar();
echo '</div>';
echo $after_widget;

$before_widget、$before_title、$after_title、$after_widgetは「WordPress 3のサイドバーにウィジェットを表示するカスタマイズ」の4項にあるregister_sidebarのハッシュキーに相当します。

5.デフォルトウィジェットについて

4項までの説明で、ウィジェットを作るための基本的な仕組みが理解できたと思います。

デフォルトのウィジェットはwp-includes/default-widgets.phpに登録されています。このファイルに書かれている各ウィジェットの処理をトレースしていけば、ウィジェット作成に関する知識をより深めることができるでしょう。

関連記事
トラックバックURL


コメントする
greeting

*必須

*必須(非表示)


ご質問のコメントの回答については、内容あるいは多忙の場合、1週間以上かかる場合があります。また、すべてのご質問にはお答えできない可能性があります。予めご了承ください。

太字イタリックアンダーラインハイパーリンク引用
[サインインしない場合はここにCAPTCHAを表示します]

コメント投稿後にScript Errorや500エラーが表示された場合は、すぐに再送信せず、ブラウザの「戻る」ボタンで一旦エントリーのページに戻り(プレビュー画面で投稿した場合は、投稿内容をマウスコピーしてからエントリーのページに戻り)、ブラウザをリロードして投稿コメントが反映されていることを確認してください。

コメント欄に(X)HTMLタグやMTタグを記述される場合、「<」は「&lt;」、「>」は「&gt;」と入力してください。例えば「<$MTBlogURL$>」は「&lt;$MTBlogURL$&gt;」となります(全て半角文字)