この記事をシェアする

【WordPress】「よく見られている記事」機能をプラグインを使わず自力実装~自作ウィジェットを添えて~

なんでその機能を実装したの? のあらましについては以下を参照。

①記事が表示された回数をカウントするための仕組みを実装

こんな感じのPHPファイルをテーマフォルダ内に用意し、header.phpとかから呼び出す。

<?php
// 投稿の詳細ページを表示した時だけ処理を行う
if (is_single() === false) {
    return;
}

// 表示中の投稿のIDを取得し、その値を使ってカスタムフィールド:display_countの値を取得
$display_count_id = get_the_ID();
$display_count = get_post_meta($display_count_id, 'display_count', true);

// display_countが空だった場合の処理
// get_post_metaの大三引数にtrueを渡しているので、
// display_countが未定義の場合空の文字列が返ってくる
if ($display_count === '') {
    // 投稿にカスタムフィールド:display_countを追加して処理終了
    $display_count = 1;
    add_post_meta($display_count_id, 'display_count', $display_count, true);
    return;
}

// display_countの値を更新する(現在の値 + 1)
update_post_meta($display_count_id, 'display_count', $display_count + 1);

投稿に表示回数をカウントするためのカスタムフィールドを追加し、投稿が表示されるたびにそのカスタムフィールドの値を更新するというすげーシンプルな作り。

これだと連続リロードとかで無限にカウント増えちゃうので、仕事で使うプログラムだったらもっと細かく制御しないと駄目よ。ここは場末の個人ブログなのでひとまず良しにしておりますが……。(まあこれも多分後で手直しするけど。気が向いたらね)

②投稿をdisplay_countの値の降順で並べて表示するための仕組みをウィジェットとして実装する

以下のコードをfunctions.phpに追記

// オリジナルウィジェットをwidgets_initフックで管理画面に登録する
function theme_register_widget() {
    register_widget( 'PopularPostWidget' );
}
add_action( 'widgets_init', 'theme_register_widget' );

/**
 * オリジナルのウィジェットを定義するクラス(WP_Widgetを継承する)
 */
class PopularPostWidget extends WP_Widget {
    
    public function __construct() {
        $widget_options = [
            'classname'                     => 'widget-popular-post',
            'description'                   => 'よく見られている記事',
            'customize_selective_refresh'   => true,
        ];
        $control_options = [];

        // WP_Widgetのコンストラクタを呼び出す
        parent::__construct( 'widget-popular-post', 'よく見られている記事', $widget_options, $control_options );
    }

    /**
     * ウィジェットのフロント側表示
     */
    public function widget( $args, $instance ) {
        // カスタムフィールド:display_countの値が1以上の記事を取得し、
        // display_countの降順でソートする
        $popular_post_query_args = [
            'meta_key'       => 'display_count',
            'meta_value_num' => 1,
            'meta_compare'   => '>=',
            'order'          => 'DESC',
            'orderby'        => 'meta_value_num',
        ];
        $popular_post_query = new WP_Query($popular_post_query_args);
        ?>
        <section id="recent-posts-2" class="widget <?=$this->widget_options['classname'];?>">
        <h2 class="widget-title"><?=$this->widget_options['description'];?></h2><nav aria-label="<?=$this->widget_options['description'];?>">
        <?php
        if ($popular_post_query->have_posts()) {
        ?>
        <ul>
            <?php
            // ループ回して記事を表示する
            while ($popular_post_query->have_posts()) {
                $popular_post_query->the_post();
            ?>
            <li><a href="<?php the_permalink();?>"><?php the_title();?></a></li>
            <?php } ?>
        </ul>
        <?php } ?>
    </section>
        <?php
        wp_reset_postdata();
    }

    /**
     * 管理画面でウィジェットを更新するためのフォームのHTMLを記載する
     * が、このウィジェットは管理画面で値を編集する必要がないので
     * 空の関数だけ置いてある
     */
    public function form( $instance ){

    }

    /** 
     * ウィジェットオプションの保存処理
     * form()と同じ理由でただ宣言してるだけ
     */
    function update($new_instance, $old_instance) {
        return $new_instance;
    }
}

するとWordPress管理画面のウィジェット一覧の中にこんな感じで出てくるので…

サイドバーなりフッターなり、表示したい場所に配置すれば良い。

別にウィジェット使わずサイドバーにベタ書きしても良かったんだけど、このブログはWordPressの公式テーマをベース(親テーマ)にして作ってるんで、できるだけWordPressのお作法に従って実装した方が良いだろうと判断。あと何だかんだ今までウィジェットの自作したことなかったので一度試してみたかったってのもある。

この記事をシェアする