wordpressで独自のカスタムウィジェットを表示させるゾ

wordpressで独自のwidgetを表示させるには以下の手順を踏みます。

①WP_Widgetクラスを拡張したクラスを作成する ②作成したクラスをwordpressに登録する ③ウィジェットエリアを登録してテンプレートで表示する

それでは順番に見ていきましょう。

WP_Widgetクラスを拡張したクラスを作成する

今回は公式ドキュメントを参考に、My_Widgetという名前で、管理画面で入力したタイトル名をウィジェットタイトルとして表示するウィジェットを作成します。

functions.phpに書いてもいいのですが、見通しが良いようにテーマ直下にwidgetsという新しいディレクトリを作って、その中にmy_widget.phpというファイルを作成します。

<?php
// widgets/my_widget.php
class My_Widget extends WP_Widget {

    /**
    * WordPress でウィジェットを登録
    */
    function __construct() {
        parent::__construct(
            'my_widget', // Base ID
            __( 'My Widget!!', 'text_domain' ), // Name
            array( 'description' => __( 'サンプルのウィジェットです。', 'text_domain' )) // Args
        );
    }

    /**
    * ウィジェットのフロントエンド表示
    *
    * @see WP_Widget::widget()
    *
    * @param array $args     ウィジェットの引数
    * @param array $instance データベースの保存値
    */
    public function widget( $args, $instance ) {
        echo $args['before_widget'];
        if ( ! empty( $instance['title'] ) ) {
            echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ). $args['after_title'];
        }
        echo __( '管理画面で入力したタイトルが表示されましたか?', 'text_domain' );
        echo $args['after_widget'];
    }

    /**
    * バックエンドのウィジェットフォーム
    *
    * @see WP_Widget::form()
    *
    * @param array $instance データベースからの前回保存された値
    */
    public function form( $instance ) {
        $title = ! empty( $instance['title'] ) ? $instance['title'] : __( '新しいタイトル', 'text_domain' );
        ?>
        <p>
        <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'タイトル:' ); ?></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
    }

    /**
    * ウィジェットフォームの値を保存用にサニタイズ
    *
    * @see WP_Widget::update()
    *
    * @param array $new_instance 保存用に送信された値
    * @param array $old_instance データベースからの以前保存された値
    *
    * @return array 保存される更新された安全な値
    */
    public function update( $new_instance, $old_instance ) {
        $instance = array();
        $instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';

        return $instance;
    }

}

作成したクラスをwordpressに登録する

作成したウィジェットを登録するには、'widgets_init'アクションフックでregister_widget()をコールします。

<?php
// functions.php
require get_theme_file_path(  'widgets/my_widget.php'  );
add_action( 'widgets_init', function(){
     register_widget( 'My_Widget' );
}); 

こうすると、先ほど作成した「My Widget!!」という名前のウィジェットが、「外観」→「ウィジェット」の一覧に表示されます。

f:id:fullstack-baby:20190920155422p:plain
My Widget!!が一覧に表示された

ウィジェットエリアを登録してテンプレートで表示する

ウィジェットエリアとは、作成したウィジェットを配置する場所になります。ウィジェットエリアを使うには、register_sidebar()という関数で登録し、dynamic_sidebar()というテンプレートタグでテンプレートファイル上の任意の場所に表示させます。

ウィジェットエリアの登録

このウィジェットエリアはいくつでも登録することができますし、多くの配布されているテーマには既にいくつかのウィジェットエリアが登録済みです。試しにTwenty Seventeenのテーマを有効化してウィジェットエリアを確認してみます。

f:id:fullstack-baby:20190920133504p:plain
Twenty Seventeenウィジェットエリア

ブログサイドバー、フッター1、フッター2、という三つのウィジェットエリアが確認できますね。

このウィジェットエリアをそのまま使ってもいいですし、エリアの使い分けをしたい、他の場所にもウィジェットを表示させたい、などという場合は新しいウィジェットエリアを登録することもできます。試しにフッター3という名前のウィジェットエリアを追加してみましょう。

<?php
// functions.phpとかに書く
add_action( 'widgets_init', function() {
    register_sidebar( array(
        'name' => 'フッター3',
        'id' => 'footer-3',
        'before_widget' => '<div>',
        'after_widget' => '</div>',
        'before_title' => '<h4>',
        'after_title' => '</h4>',
    ) );
} );

f:id:fullstack-baby:20190920151210p:plain
'フッター3' ウィジェットエリアが追加された

ウィジェットエリアの表示

今作ったフッター3というウィジェットエリアを表示させたい場所でdynamic_sidebar()を実行します。関数名が紛らわしいんですが、別にsidebar.php以外にも、テンプレートファイル内の好きな場所でこの関数を使用してウィジェットを表示させることができます。ちなみに、is_active_sidebar('footer-3')というのは、'footer-3'というidのウィジェットエリアが登録されているかを判定する条件分岐タグです。

<?php if ( is_active_sidebar( 'footer-3' ) ) : ?>
    <div id="footer-3" class="footer-3 widget-area" role="complementary">
                 <?php // register_sidebar()で決めたdを引数に与える  ?>
        <?php dynamic_sidebar( 'footer-1' ); ?>
    </div>
<?php endif; ?>

できましたでしょうか?

次回はもうちょっと使い道のあるウィジェットを実際に作成してみます!よきwordpressライフを!