WordPress には、いろいろなウィジェットが用意されている。ウィジェットはサイドバーなどに表示できるブログのパーツだ。当サイトでは、標準のウィジェットの「最近の投稿」「カテゴリー」「カレンダー」「アーカイブ」を使っている(AUTHORS はこれから紹介する独自のウィジェット)。
ウィジェットをサイドバーに表示するには、管理画面のダッシュボードで、「外観」→「ウィジェット」の順に選んで、「利用できるウィジェット」に表示されている各種ウィジェットを、右側のサイドバーにドラッグするだけでよい。ウィジェットによっては設定があり、表示形式や表示内容をカスタマイズできる。
ウィジェット作成の概要
当サイトは、複数の著者がブログを書いているので、投稿者ごとの投稿を表示できるウィジェットを作ってみた。WordPress に独自のウィジェットを追加するには、WP_Widget クラスを継承したクラスを持つプラグインを作成すればよい。難しくはないが、PHP と WordPress の知識がある程度必要なので使えるかどうかわからないがダウンロードもできるようにしてみた。
単純なウィジェットであれば、コンストラクターと widget($args, $instance) メソッドをオーバーライドし、作成したウィジェットを登録するだけでよい。WP_Widget クラスの定義は wp-includes/widgets.php に記述されているので、作成する前に目を通しておくと何をオーバーライドすべきなのかわかるだろう。今回は、ウィジェットのタイトル変更ぐらいはできるようにしたかったので、設定画面を操作する際のメソッドもオーバーライドした。なお、利用している WordPress のバージョンは、3.5.2だ。
クラスの定義
作成するクラスは、概要で述べたように WP_widget を継承する。クラス名は、WordPress で定義されているクラス名や、プラグインで利用されているクラス名と重複しないようにする。
class UB_WP_Widget_Users extends WP_Widget { ... }
コンストラクタの定義
コンストラクタは、ウィジェットが生成されたときに呼び出される。引数とウィジェットのオプションをセットして、WP_Widget のコンストラクタを呼び出す(parent::__construct(…) の部分)。
function __construct() { $widget_ops = array('classname' => 'widget_recent_entries', 'description' => '投稿者のリスト' ); parent::__construct('users-posts', '投稿者', $widget_ops); $this->alt_option_name = 'widget_users_entries'; }
WP_Widget のコンストラクタの定義は、以下のようになっている。$id_base はウィジェットの ID で、小文字で一意の値を指定する必要がある。指定しなかった場合は、クラス名を利用するようだ。$name は設定ページで表示するウィジェットの名前だ。今回は横着をして、名前をハードコーディングしている。$widget_options は wp_register_sidebar_widget() に渡すオプション、$control_options は、wp_register_widget_control() に渡すオプションなる。
function __construct( $id_base = false, $name, $widget_options = array(), $control_options = array() )
widget メソッドの定義
widget メソッドは、ブログにウィジェットを表示するときのコードを記述するためのメソッドで、必ずオーバーライドする必要がある。引数で渡される $args は表示のため変数を含むオプションで、extract 関数に渡すと、$before_title, $after_title, $before_widget, $after_widget が利用できるようになる。$instance は、設定値を取得するための変数だ。コードは単純なので、処理の内容をコメントで入れた。
function widget($args, $instance) { if ( ! isset( $args['widget_id'] ) ) $args['widget_id'] = $this->id; ob_start(); // $args をを展開 extract($args); // タイトルを設定、設定画面でタイトルが設定されていない場合は 'AUTHORS' $title = apply_filters('widget_title', empty($instance['title']) ? 'AUTHORS' : $instance['title'], $instance, $this->id_base); // ユーザーを取得、ただし管理者は除く $users = get_users(array('exclude' => array(1))); ?> // ウィジェットの前部分表示 <?php echo $before_widget; ?> // タイトル表示 <?php if ( $title ) echo $before_title . $title . $after_title; ?> <ul> // ユーザーごとのリンクとユーザー名を表示 <?php foreach($users as $user): ?> <li><a href="<?php echo site_url('/archives/author/' . $user->user_nicename); ?>" title="<?php echo $user->display_name; ?>"><?php echo $user->display_name; ?></a></li> <?php endforeach; ?> </ul> // ウィジェットの後ろ部分表示 <?php echo $after_widget; ?> <?php }
設定画面のメソッドの定義
設定画面のメソッドは、設定画面の内容を表示する form($instance) メソッドと、更新された内容を保存する update($new_instance, $old_instance) メソッドをオーバーライドすればよい。今回は、ウィジェットのタイトルだけを編集可能にしたので、タイトルを入力、保存しているだけだ。
function update( $new_instance, $old_instance ) { $instance = $old_instance; $instance['title'] = strip_tags($new_instance['title']); return $instance; } function form( $instance ) { $title = isset( $instance['title'] ) ? esc_attr( $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 $title; ?>" /></p> <?php }
ウィジェットの登録
最後に、ウィジェットの登録を行うコードを記述する。これはクラス内ではなく、クラス外(つまり、PHP が呼び出されたらすぐに実行される)に記述している。add_action の引数で create_function() 関数を使って登録すれば短くすむのだが、標準のウィジェットのコードと記述方法を合わせた。
function ub_wp_widgets_init() { if ( !is_blog_installed() ) return; register_widget('UB_WP_Widget_Users'); do_action('widgets_init'); } add_action('init', 'ub_wp_widgets_init', 1);
ダウンロード
長々と書きましたが、最後まで読んでいただきありがとうございます。少し横着をしている箇所もあり、つたないコードではありますが、もし使ってみたいという方がいらっしゃいましたら、
ub-wp-widget
からダウンロードできます。バグがあったら、教えてください。利用方法は、通常のプラグインと同じで ZIP ファイル内のub-wp-widget ディレクトリを wp-content/plugins/ ディレクトリに置いて有効化するだけです。
こんにちは,
ub-wp-widgetをいつも使わせていただいております.
twentyfourteenテーマにおいて,ub-wp-widgetを有効化するとサーバーエラーが出たため,
確認しましたところ,widgets.php70行目 do_action(‘widgets_init’); の部分が原因のようでしたので,
以下のようにub_wp_widgets_init()を書き換えたところ正常に動作致しました.
function ub_wp_widgets_init() {
register_widget(‘UB_WP_Widget_Users’);
}
add_action(‘widgets_init’, ‘ub_wp_widgets_init’);
ご利用いただき、ありがとうございます。
また、不具合のご指摘、ありがとうございます!
確認して、ダウンロードできるようにした ZIP ファイルも修正しておきます。