WordPress ウィジェット を作る

modified at:25 June 2015

今回は、ウィジェットの作り方です。

ウィジェットはサイドバーに表示される小さめのプラグインといった感じですね。実際、ウィジェットもプラグインとして作るわけです。ウィジェットを作ってみてそれからプラグインに入るといろいろわかりやすいのではないかと思いました。

いつものようにWordPress CodexのWordPress ウィジェット APIなどを参考にさせていただいています。

ウィジェットはプラグインとして作る

ウィジェットはプラグインとして作ります。プラグインを作るには、プラグインメインファイルの冒頭にコメントとして次のような情報を書き込んでおけば良いのでした。

      <?php
/*
Plugin Name: (プラグインの名前)
Plugin URI: (プラグインの説明と更新を示すページの URI)
Description: (プラグインの短い説明)
Version: (プラグインのバージョン番号。例: 1.0)
Author: (プラグイン作者の名前)
Author URI: (プラグイン作者の URI)
License: (ライセンス名の「スラッグ」 例: GPL2)
*/
   

これを記述したファイルを含むディレクトリをwp-contents/plugins/配下に置くと、WordPressによってプラグインと認識されます。管理者としてログインし、プラグインメニューを開くと一覧の中にプラグインの名前とその情報が表示されていることでしょう。

そのプラグイン(ウィジェット)を有効化すれば、管理メニューの「外観」->「ウィジェット」の中にあなたのウィジェットを見つけることができます。

Widget作成Topへ

プラグインではなくウィジェットにするには、WordPressのWP_Widgetクラスを継承したPHPクラスを作り、そのクラスをウィジェットとして登録します。基本的な構成は次のようになります。

なお、後ほど見るように管理者がウィジェットのために設定する項目は、WordPressのデータベースに登録されます。

      class CD_My_Widget extends WP_Widget {

          // constructor
          function CD_My_Widget() {
                    /* ... */
          }

          // widget form :ウィジェットの設定画面
          function form($instance) {
                    /* ... */
          }

          // widget update :データベースに登録する値の処理
          function update($new_instance, $old_instance) {
                    /* ... */
          }

          // widget display :ウィジェットとして表示する内容の記述
          function widget($args, $instance) {
                    /* ... */
          }
}

// register widget :
add_action('widgets_init',  function() {
        register_widget("CD_My_Widget"); // WP_Widget を継承したクラス名を登録
    }
);
   

add_actionの第一引数にフックとして「widgets_init」を指定することで、widgetの初期化の時に第二引数の「文字列で指定された」関数が(フックされたタイミングで)実行されます(引数は文字列であることに注意)。上の例は、関数名を指定する第二引数に無名関数を定義しています。無名関数は変数へ代入できるのでこのような使い方ができます。

これは、下のものと同等です。

      add_action('widgets_init',  'hoge');

function hoge() { register_widget("CD_My_Widget"); }
   

このようにして、フックのタイミングでregister_widget("…")関数が呼び出され、クラス名「CD_My_Widget」を登録します。

次に、ウィジェットの各メソッドを見ていきましょう。

  1. コンストラクタ: function CD_My_Widget() { /* … */ }
  2. 設定を登録する管理画面フォーム: function form($instance) { /* … */ }
  3. データベースに登録する値を処理する:function update($new_instance, $old_instance) { /* … */ }
  4. ウィジェットコンテンツを表示する: function widget($args, $instance) { /* … */ }

コンストラクタ

継承した親のコンストラクタを呼び出し、このウィジェットにはcd_widgetという名前を付けました。このウィジェットのクラス名はCD_My_Widgetなので、コンストラクタは、

          function CD_My_Widget() {
        parent::WP_Widget(false, $name = 'cd_widget');
    }
   

となります(これはphp4の書き方なのですね。php5風に__construct()としても大丈夫です)。

ここでは先ず、最低限の内容として「タイトル」と「テキスト」を入力し、登録、表示させるウィジェットを完成させることにします。その際、それぞれに‘title’‘text’という(自分で決めた)キーを用いています。

設定を登録する管理画面フォーム

管理画面でウィジェットをサイドバーにドラッグ&ドロップした場所で表示される設定画面です。

          function form($instance) {
        if( $instance) {
            $title = esc_attr($instance['title']);
            $text = esc_attr($instance['text']);
        } else {
            $title = '';
            $text = '';
        }
    ?>
        <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 $title; ?>" />
        </p>

        <p>
            <label for="<?php echo $this->get_field_id('text'); ?>">
                <?php _e('Text:'); ?>
            </label>
            <input class="widefat" id="<?php echo $this->get_field_id('text'); ?>"
                   name="<?php echo $this->get_field_name('text'); ?>"
                   type="text"
                   value="<?php echo $text; ?>" />
        </p>

    <?php
    }
   
   

既に登録されている値があれば、「< > & “ ‘ (小なり、大なり、アンパサンド、ダブルクォート、シングルクォート)」 文字参照をエンコードして表示しています。

データベースに登録する値を処理する

          function update($new_instance, $old_instance) {
        $instance = $old_instance;

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

        return $instance;
    }
   

新しく登録する値からHTMLタグを剥ぎ取りハッシュで返します。設定値は「wp_optionsテーブル」に1レコードとして登録されます。

ウィジェットコンテンツを表示する

          function widget($args, $instance) {
        extract( $args );
        $title = apply_filters('widget_title', $instance['title']);
        $text = $instance['text'];

        echo $before_widget;
        // ウィジェット本体を囲む
        echo '<div class="widget-text cd_my_widget_block">';

        // 「タイトル」の表示
        if ( $title ) {
            echo $before_title . $title . $after_title;
        }

        // 「テキスト」の表示
        if( $text ) {
            echo '<p class="cd_my_widget_text">'.$text.'</p>';
        }

        echo '</div>';
        echo $after_widget;
    }
   

タイトルとテキストを表示するだけですが、立派にウィジェットが完成しました。

CSSファイルを読み込むTopへ

スタイルシートで表現をカスタマイズしたいですね。

スタイルシートを読み込むには、

          wp_register_style('識別子', 'cssファイルへのパス', array('依存する他の識別子'), 'ヴァージョン番号');
    wp_enqueue_style('識別子');
   

この2つの関数で実現できます。まずはwp_register_style関数で登録だけしておいて、そのスタイルシートを使う場面でwp_enqueue_style関数で読み込ませる、という使い方ができます。

wp_register_style 関数

       wp_register_style(  $handle, $src, $deps = array(), $ver = false, $media = 'all'  );

$handle … スタイルシートを登録する「識別子」。初期値: なし。

$src … このスタイルシートのファイル名(パス付き)。初期値: false 。

$deps … このスタイルシートが依存していて、これよりも先に読み込まれていなければならないスタイシートの「識別子」を配列で記述する。初期値: array() 。

$ver … このスタイルシートのヴァージョン番号。初期値: false 。

$media … どの種類のmediaに対するスタイルシートなのかを指定する。例: ‘all’, ‘screen’, ‘handheld’, ‘print’。 初期値: ‘all’ 。

wp_enqueue_style 関数

       wp_enqueue_style( $handle, $src = false, $deps = array(), $ver = false, $media = 'all' )

引数は、wp_register_styleと全く同じです。ソースを読むとwp_enqueue_style関数だけで引数があればスタイルシートの登録と同時に読み込ませられることがわかりました。確かめてみたら

       wp_enqueue_style('cd_jp_calendar_style', plugins_url('', __FILE__) . '/cd_jp_calendar.css', array(), '201406');

とすることでスタイルシートを読み込ませることができました。

いつスタイルシートを読み込ませるか

使いもしないのにスタイルシートだけを読み込ませておくのは無駄です。どのタイミングで読み込ませるかを指定するのがフックを指定してのadd_action関数ですね。

          add_action( 'admin_init', '実行するメソッド');
    add_action( 'admin_menu', '実行するメソッド');
    add_action( 'wp_enqueue_scripts', '実行するメソッド');
   

admin_initフックは、管理画面が表示される時一番初めに実行する関数を登録します。

admin_menuフックは、管理画面が表示される時メニューまたはサブメニューの表示のされ方を指定する関数を登録します。

wp_enqueue_scriptsフックは、コンテンツが表示されている時に読み込ませるフックです。

ここではスタイルシートについてだけ述べていますが、javascriptファイルを読み込ませる時もほとんど同じです。wp_register_stylewp_register_scriptに、wp_enqueue_stylewp_enqueue_scriptに置き換えるだけです。

      add_action('wp_enqueue_scripts', 'cd_enqueue_scripts');

function cd_enqueue_scripts() {
    wp_enqueue_style('cd_my_widget_style', plugins_url('', __FILE__) . '/cd_my_widget.css', array(), '201406');
}
   

Widget 完成形Topへ

クラスの内部も記述した全体です。

File: CD_My_Widget.php
  1 <?php
  2 /*
  3   Plugin Name:	CD test Widget
  4   Plugin URI: 	http://www.co-machi.org/plugins/cd_my_widget/
  5   Description: 	テストウィジェットです。
  6   Author: 		Denn
  7   Author URI: 	http://www.co-machi.org/
  8   Version: 		201406
  9   License:		GPL2
 10  */
 11 
 12 if (!class_exists('CD_My_Widget')) :
 13     //require_once WP_PLUGIN_DIR . '/cd_my_widget/CD_Foge.php';
 14 
 15     class CD_My_Widget extends WP_Widget {
 16 
 17         // constructor
 18         function CD_My_Widget() {
 19             parent::WP_Widget(false, $name = 'cd_widget');
 20         }
 21 
 22         // widget form :ウィジェットの設定画面
 23         function form($instance) {
 24             if ($instance) {
 25                 $title = esc_attr($instance['title']);
 26                 $text = esc_attr($instance['text']);
 27             } else {
 28                 $title = '';
 29                 $text = '';
 30             }
 31             ?>
 32             <p>
 33                 <label for="<?php echo $this->get_field_id('title'); ?>">
 34                     <?php _e('Title:'); ?>
 35                 </label>
 36                 <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>"
 37                        name="<?php echo $this->get_field_name('title'); ?>"
 38                        type="text"
 39                        value="<?php echo $title; ?>" />
 40             </p>
 41 
 42             <p>
 43                 <label for="<?php echo $this->get_field_id('text'); ?>">
 44                     <?php _e('Text:'); ?>
 45                 </label>
 46                 <input class="widefat" id="<?php echo $this->get_field_id('text'); ?>"
 47                        name="<?php echo $this->get_field_name('text'); ?>"
 48                        type="text"
 49                        value="<?php echo $text; ?>" />
 50             </p>
 51 
 52             <?php
 53         }
 54 
 55         // widget update :データベースに登録する値の処理
 56         function update($new_instance, $old_instance) {
 57             $instance = $old_instance;
 58 
 59             $instance['title'] = strip_tags($new_instance['title']);
 60             $instance['text'] = strip_tags($new_instance['text']);
 61 
 62             return $instance;
 63         }
 64 
 65         // widget display :ウィジェットとして表示する内容の記述
 66         function widget($args, $instance) {
 67             extract($args);
 68             $title = apply_filters('widget_title', $instance['title']);
 69             $text = $instance['text'];
 70 
 71             echo $before_widget;
 72             // ウィジェット本体を囲む
 73             echo '<div class="widget-text cd_my_widget_block">';
 74 
 75             // 「タイトル」の表示
 76             if ($title) {
 77                 echo $before_title . $title . $after_title;
 78             }
 79 
 80             // 「テキスト」の表示
 81             if ($text) {
 82                 echo '<p class="cd_my_widget_text">' . $text . '</p>';
 83             }
 84 
 85             echo '</div>';
 86             echo $after_widget;
 87         }
 88 
 89     }
 90 
 91     endif;
 92 
 93 // register widget
 94 add_action('widgets_init', function() {
 95     register_widget("CD_My_Widget");
 96 });
 97 
 98 // register stylesheet
 99 add_action('wp_enqueue_scripts', 'cd_enqueue_scripts');
100 
101 function cd_enqueue_scripts() {
102     wp_register_style('cd_my_widget_style', plugins_url('', __FILE__) . '/cd_my_widget.css', array(), '201406');
103     wp_enqueue_style('cd_my_widget_style');
104 }

今回のウィジェットでは必要ありませんでしたが、別ファイルで定義した関数やクラスを使うためにインクルードする一行も入れてあります。

       require_once WP_PLUGIN_DIR . '/cd_my_widget/CD_Foge.php';

以上、ウィジェットの作り方でした。

プラグインより簡単に作れそう、と思っていただけたらうれしいです。 皆さんもウィジェット作りに挑戦してみてください。

  created at:23 June 2015




[投稿する]場合は、 枠の中の図形をマウスでドラッグして、(あるいは指で)なぞって下さい。それほど厳密でなくても大丈夫です。