組み込みウィジェットとスタンドアロンウィジェット

デフォルトのWordPressインストールにはウィジェットのセットが含まれています。これらの標準ウィジェットに加えて、テーマやプラグインによって追加のウィジェットを含めることができます。テーマやプラグインに組み込まれたウィジェットの利点は、追加機能を提供し、ウィジェットの数を増やすことです。

欠点は、テーマが変更されたりプラグインが無効化された場合、プラグインやテーマウィジェットの機能が失われることです。しかし、ウィジェットのデータと設定はオプションテーブルに保存され、テーマやプラグインが再アクティブ化されると復元されます。

テーマにウィジェットを含めると、そのテーマがアクティブな場合にのみ使用できます。ユーザーがテーマを変更することを決定した場合、そのウィジェットへのアクセスを失います。しかし、ウィジェットがプラグインに含まれている場合、ユーザーはテーマを変更してもウィジェットの機能へのアクセスを失うことはありません。

ウィジェットの構造

視覚的に、ウィジェットは2つの領域で構成されています:

  • 1. タイトルエリア
  • 2. ウィジェットオプション

例えば、以下は管理画面とフロントエンドにおける組み込みテキストウィジェットのレイアウトです:

サンプル編集可能ウィジェット
管理エリアのウィジェットフォーム。

サイト訪問者に表示されるウィジェット
サイト訪問者に表示されるウィジェット。

このウィジェットのHTML出力は次のようになります:

  1. <div id="text-7" class="widget widget_text">
  2. <div class="widget-wrap">
  3. <h4 class="widgettitle">
  4. This is a text widget
  5. </h4><!-- .widgettitle -->
  6. <div class="textwidget">
  7. I can put HTML in here. <a href="http://google.com/">Search me!</a>
  8. </div><!-- .textwidget -->
  9. </div><!-- .widget-wrap -->
  10. </div><!-- #text-7 -->

各ウィジェットは、表示されるデータに関連するHTMLを出力する独自の方法を持っています。ウィジェットのラッパータグは、表示されるウィジェットエリアによって定義されます。

組み込みテキストウィジェットのようなウィジェットを作成するために必要なPHPコードは次のようになります:

  1. <?php
  2. class My_Widget extends WP_Widget {
  3. public function __construct() {
  4. parent::__construct(
  5. 'my-text', // Base ID
  6. 'My Text' // Name
  7. );
  8. add_action( 'widgets_init', function() {
  9. register_widget( 'My_Widget' );
  10. });
  11. }
  12. public $args = array(
  13. 'before_title' => '<h4 class="widgettitle">',
  14. 'after_title' => '</h4>',
  15. 'before_widget' => '<div class="widget-wrap">',
  16. 'after_widget' => '</div></div>',
  17. );
  18. public function widget( $args, $instance ) {
  19. echo $args['before_widget'];
  20. if ( ! empty( $instance['title'] ) ) {
  21. echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ) . $args['after_title'];
  22. }
  23. echo '<div class="textwidget">';
  24. echo esc_html__( $instance['text'], 'text_domain' );
  25. echo '</div>';
  26. echo $args['after_widget'];
  27. }
  28. public function form( $instance ) {
  29. $title = ! empty( $instance['title'] ) ? $instance['title'] : esc_html__( '', 'text_domain' );
  30. $text = ! empty( $instance['text'] ) ? $instance['text'] : esc_html__( '', 'text_domain' );
  31. ?>
  32. <p>
  33. <label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php echo esc_html__( 'Title:', 'text_domain' ); ?></label>
  34. <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>">
  35. </p>
  36. <p>
  37. <label for="<?php echo esc_attr( $this->get_field_id( 'Text' ) ); ?>"><?php echo esc_html__( 'Text:', 'text_domain' ); ?></label>
  38. <textarea class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'text' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'text' ) ); ?>" type="text" cols="30" rows="10"><?php echo esc_attr( $text ); ?></textarea>
  39. </p>
  40. <?php
  41. }
  42. public function update( $new_instance, $old_instance ) {
  43. $instance = array();
  44. $instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
  45. $instance['text'] = ( ! empty( $new_instance['text'] ) ) ? $new_instance['text'] : '';
  46. return $instance;
  47. }
  48. }
  49. $my_widget = new My_Widget();

上記のコードは、記事の後半で詳細に説明されます。

ウィジェットの開発

ウィジェットを作成して表示するには、次の手順を実行する必要があります:

  • 1. 標準のWP_Widgetクラスを拡張してウィジェットのクラスを作成し、そのいくつかの関数を使用します。
  • 2. ウィジェットを登録して、ウィジェット画面で利用できるようにします。
  • 3. テーマにウィジェットを追加するためのウィジェットエリアが少なくとも1つあることを確認します。

あなたのウィジェットクラス

WP_Widgetクラスはwp-includes/class-wp-widget.phpにあります。

  1. <?php
  2. class My_Widget extends WP_Widget {
  3. public function __construct() {
  4. // actual widget processes
  5. }
  6. public function widget( $args, $instance ) {
  7. // outputs the content of the widget
  8. }
  9. public function form( $instance ) {
  10. // outputs the options form in the admin
  11. }
  12. public function update( $new_instance, $old_instance ) {
  13. // processes widget options to be saved
  14. }
  15. }

これらの各関数のドキュメントはウィジェットクラスコードにあります:

  • 1. construct: 管理画面でウィジェットを説明、名前、表示幅で設定します。
  • 2. widget: ウィジェットオプションを処理し、ページにHTMLを表示します。$argsパラメータは、ウィジェットタイトルクラスとウィジェットコンテンツクラスを表示するために使用できるHTMLを提供します。
  • 3. form: ウィジェットのオプションを設定するために使用されるフォームを表示します。ウィジェットにオプションがない場合、この関数はスキップできます(ただし、空であっても含めることが最良のプラクティスです)。
  • 4. update: ウィジェットオプションをデータベースに保存します。ウィジェットにオプションがない場合、この関数はスキップできます(ただし、空であっても含めることが最良のプラクティスです)。

ウィジェットの登録

register_widget()関数はウィジェットを登録するために使用されます。

この関数をwidgets_initフックを使用して呼び出します:

  1. <?php
  2. add_action( 'widgets_init', 'wpdocs_register_widgets' );
  3. function wpdocs_register_widgets() {
  4. register_widget( 'My_Widget' );
  5. }

ウィジェットをラップするHTMLや、タイトルとウィジェットコンテンツのクラスは、register_sidebar()を使用してウィジェットエリアを登録する際に指定されます。

テキストウィジェットの例

この記事の冒頭の例からテキストウィジェットを構築します。まず、WP_Widgetクラスを拡張するウィジェットクラスを設定します。

クラスコンストラクタでは、親コンストラクタを呼び出し、ウィジェットのベースIDと名前を渡します。また、クラスコンストラクタ内でwidgets_initアクションにフックしてウィジェットを登録します。

次に、ウィジェットを作成する際に使用する引数を宣言します。定義しなければならない引数は4つ、before_titleafter_titlebefore_widgetafter_widgetです。これらの引数は、ウィジェットのタイトルとウィジェット自体をラップするコードを定義します。

引数を定義した後、ウィジェットの関数を定義します。この関数は2つのパラメータを受け取ります。前述の$args配列とウィジェットの$instanceで、フォームからのオプションを処理し、サイトのフロントエンドにウィジェットのHTMLを表示する関数です。上記の例では、ウィジェット関数は単にウィジェットタイトルを出力し、widget_titleフィルターを通します。その後、シンプルなウィジェットラッパーとウィジェットのテキストフィールドの内容を出力します。例に示されているように、$instanceに保存されているウィジェットのオプションにアクセスできます。

次に、フォーム関数を定義します。この関数は1つのパラメータ、$instanceを受け取り、ユーザーがウィジェットを作成するためにウィジェット管理画面で使用するフォームを出力します。上記の例では、関数は$title$text変数を定義し、それらを以前に入力された値に設定します(その値が存在する場合)。その後、タイトル用のテキストフィールドとテキストコンテンツ用のテキストエリアを持つシンプルなフォームを出力します。

最後に、更新関数を定義します。この関数は2つのパラメータ、$new_instance$old_instanceを受け取り、提出されたときに新しいオプションでウィジェットを更新する責任があります。ここでは、$instanceを空の配列として定義します。次に、タイトルとテキストのキーを$new_instanceの値に設定します(それらが存在する場合)。その後、$instanceを返します。

最後に、上記のすべてが定義されたら、新しいウィジェットクラスをインスタンス化し、作業をテストします。

サンプルウィジェット

  1. <?php
  2. /**
  3. * Adds Foo_Widget widget.
  4. */
  5. class Foo_Widget extends WP_Widget {
  6. /**
  7. * Register widget with WordPress.
  8. */
  9. public function __construct() {
  10. parent::__construct(
  11. 'foo_widget', // Base ID
  12. 'Foo_Widget', // Name
  13. array( 'description' => __( 'A Foo Widget', 'text_domain' ) ) // Args
  14. );
  15. }
  16. /**
  17. * Front-end display of widget.
  18. *
  19. * @see WP_Widget::widget()
  20. *
  21. * @param array $args Widget arguments.
  22. * @param array $instance Saved values from database.
  23. */
  24. public function widget( $args, $instance ) {
  25. extract( $args );
  26. $title = apply_filters( 'widget_title', $instance['title'] );
  27. echo $before_widget;
  28. if ( ! empty( $title ) ) {
  29. echo $before_title . $title . $after_title;
  30. }
  31. echo __( 'Hello, World!', 'text_domain' );
  32. echo $after_widget;
  33. }
  34. /**
  35. * Back-end widget form.
  36. *
  37. * @see WP_Widget::form()
  38. *
  39. * @param array $instance Previously saved values from database.
  40. */
  41. public function form( $instance ) {
  42. if ( isset( $instance['title'] ) ) {
  43. $title = $instance['title'];
  44. } else {
  45. $title = __( 'New title', 'text_domain' );
  46. }
  47. ?>
  48. <p>
  49. <label for="<?php echo $this->get_field_name( 'title' ); ?>"><?php _e( 'Title:' ); ?></label>
  50. <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 ); ?>" />
  51. </p>
  52. <?php
  53. }
  54. /**
  55. * Sanitize widget form values as they are saved.
  56. *
  57. * @see WP_Widget::update()
  58. *
  59. * @param array $new_instance Values just sent to be saved.
  60. * @param array $old_instance Previously saved values from database.
  61. *
  62. * @return array Updated safe values to be saved.
  63. */
  64. public function update( $new_instance, $old_instance ) {
  65. $instance = array();
  66. $instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
  67. return $instance;
  68. }
  69. } // class Foo_Widget

このサンプルウィジェットは、次のようにwidgets_initフックで登録できます:

  1. <?php
  2. // Register Foo_Widget widget
  3. add_action( 'widgets_init', 'register_foo' );
  4. function register_foo() {
  5. register_widget( 'Foo_Widget' );
  6. }

名前空間を使用した例

PHP 5.3で名前空間を使用する場合、次の例のようにコンストラクタを直接呼び出す必要があります:

  1. <?php
  2. namespace a\b\c;
  3. class My_Widget_Class extends \WP_Widget {
  4. public function __construct() {
  5. parent::__construct( 'baseID', 'name' );
  6. }
  7. // ... rest of the functions
  8. }

そして、ウィジェットを登録するには:

  1. <?php
  2. // Register Foo_Widget widget
  3. add_action( 'widgets_init', 'register_my_widget' );
  4. function register_my_widget() {
  5. register_widget( 'a\b\c\My_Widget_Class' );
  6. }

詳細についてはこの回答をstack exchangeで参照してください

特別な考慮事項

サイドバーではなく別のテンプレートファイル内でウィジェットを使用したい場合、the_widget()を使用してプログラム的に表示できます。この関数はウィジェットクラス名を受け入れます。ウィジェットクラス名を次のように関数に渡します:

  1. <?php the_title(); ?>
  2. <div class="content">
  3. <?php the_content(); ?>
  4. </div><!-- .content -->
  5. <div class="widget-section">
  6. <?php the_widget( 'My_Widget_Class' ); ?>
  7. </div><!-- .widget-section -->

特定のページの特定のエリアでウィジェットを使用する必要がある場合、たとえば、サイトのフロントページのセクションでフォームの横にイベントのリストを表示したり、ナビゲーションの横にメガメニューでメールキャプチャフォームを表示したりする場合に、このアプローチを使用することをお勧めします。