WordPressで「人気記事」を表示するとき、期間を絞ってランキングを出したいと思ったことはありませんか? さらに、新着記事も同じ仕組みで出せると便利ですよね。今回は、新着記事や人気記事(週間・月間・年間・全期間)を切り替えて表示できるショートコードを紹介します。
実現したいこと
- 新着記事を表示したい
- 人気記事を「週間」「月間」「年間」「全期間」で切り替えて表示したい
- すべてを1つのショートコードで管理したい
実装のゴールとして、以下のショートコードをページや投稿に貼るだけで、指定の一覧を表示できるようにします。
<!-- 新着記事 -->
[swell_popular_posts period="recent"]
<!-- 週間人気記事 -->
[swell_popular_posts period="weekly"]
<!-- 月間人気記事 -->
[swell_popular_posts period="monthly"] 
<!-- 年間人気記事 -->
[swell_popular_posts period="yearly"]
<!-- 全期間人気記事 -->
[swell_popular_posts period="all"]期間指定の仕組み
WordPressは、WP_Query を使うことで投稿一覧を自由にカスタマイズできます。その際、以下のようなポイントがあります。
- 新着記事:投稿日の降順で絞り込む
- 人気記事:PVカウントなどのメタキーを使い、数値が多い順に並べる
- 期間を絞る:date_queryを利用して「1週間以内」「1ヶ月以内」「1年以内」などを指定する
これらを切り替えるために、ショートコードの属性(ここでは period という名前)を読み取り、分岐させる仕組みにします。
コード例
以下のコードを、テーマの functions.php か、オリジナルのプラグインに追記してください。例では、PV数などを保存しているメタキー(例:SWELL_CT_KEY) を使って人気記事を並び替える想定です。
/**
 * 人気記事 & 新着記事 を表示するショートコード
 *
 *   // 週間人気記事
 *  // 月間人気記事
 *   // 年間人気記事
 *      // 全期間人気記事
 *   // 新着記事
 */
function swell_popular_posts_shortcode( $atts ) {
    // ショートコードの属性を設定
    $atts = shortcode_atts(
        array(
            'period' => 'weekly', // デフォルトは "週間" 表示
        ),
        $atts,
        'swell_popular_posts'
    );
    // 初期パラメータ
    $args = array(
        'posts_per_page'      => 6,
        'post_type'           => 'post',
        'ignore_sticky_posts' => 1,
    );
    // period 属性の値によってクエリを分岐
    switch ( $atts['period'] ) {
        case 'recent':
            // 新着記事 (投稿日の降順)
            $args['orderby'] = 'date';
            $args['order']   = 'DESC';
            // 人気記事と違い、メタキーなどは使用しない
            break;
        case 'monthly':
            // 月間の人気記事
            $args['meta_key'] = SWELL_CT_KEY;    // 人気度を保存しているメタキー
            $args['orderby']  = 'meta_value_num';
            $args['order']    = 'DESC';
            $args['date_query'] = array(
                array(
                    'after'     => '1 month ago',
                    'inclusive' => true,
                ),
            );
            break;
        case 'yearly':
            // 年間の人気記事
            $args['meta_key'] = SWELL_CT_KEY;
            $args['orderby']  = 'meta_value_num';
            $args['order']    = 'DESC';
            $args['date_query'] = array(
                array(
                    'after'     => '1 year ago',
                    'inclusive' => true,
                ),
            );
            break;
        case 'all':
            // 全期間の人気記事
            $args['meta_key'] = SWELL_CT_KEY;
            $args['orderby']  = 'meta_value_num';
            $args['order']    = 'DESC';
            // 全期間なので date_query は指定しない
            break;
        case 'weekly':
        default:
            // 週間の人気記事
            $args['meta_key'] = SWELL_CT_KEY;
            $args['orderby']  = 'meta_value_num';
            $args['order']    = 'DESC';
            $args['date_query'] = array(
                array(
                    'after'     => '1 week ago',
                    'inclusive' => true,
                ),
            );
            break;
    }
    // WP_Query の実行
    $the_query = new WP_Query( $args );
    // 出力のバッファリング開始
    ob_start();
    if ( $the_query->have_posts() ) :
        echo '<ul class="p-postList -type-card -w-ranking">';
        while ( $the_query->have_posts() ) :
            $the_query->the_post();
            ?>
            <li class="p-postList__item">
                <a href="<?php the_permalink(); ?>" class="p-postList__link">
                    <div class="p-postList__thumb c-postThumb">
                        <figure class="c-postThumb__figure">
                            <?php if ( has_post_thumbnail() ) : ?>
                                <img class="c-postThumb__img u-obf-cover"
                                     src="<?php the_post_thumbnail_url('medium'); ?>"
                                     alt="<?php the_title(); ?>"
                                     sizes="(min-width: 600px) 320px, 50vw">
                            <?php endif; ?>
                        </figure>
                    </div>
                    <div class="p-postList__body">
                        <div class="p-postList__title"><?php the_title(); ?></div>
                        <div class="p-postList__meta"></div>
                    </div>
                </a>
            </li>
            <?php
        endwhile;
        echo '</ul>';
        wp_reset_postdata();
    endif;
    // バッファの内容を返す
    return ob_get_clean();
}
add_shortcode( 'swell_popular_posts', 'swell_popular_posts_shortcode' );SWELL_CT_KEY とは?
上記の例では、PV数などを保存しているメタキーとして SWELL_CT_KEY を使用しています。これはSwellテーマでPV数を保存する際に使われるキーの例ですが、実際には自分のブログやアクセスカウントプラグインに合わせて変更してください。
もし別のメタキー(例:views)を使っているなら、適宜読み替えて使いましょう。
使い方
- functions.phpかプラグインファイルにコードを貼り付ける
- 投稿や固定ページの本文に以下のようにショートコードを埋め込む
<!-- 新着記事 -->
'[swell_popular_posts period="recent"]'
<!-- 週間人気記事 -->
[swell_popular_posts period="weekly"]
<!-- 月間人気記事 -->
[swell_popular_posts period="monthly"]
<!-- 年間人気記事 -->
[swell_popular_posts period="yearly"]
<!-- 全期間人気記事 -->
[swell_popular_posts period="all"]
たとえば、トップページのカスタムページやサイドバーなど、ウィジェットの表示をショートコード対応させることで、簡単に「今週の人気記事」「新着記事」のようなブロックを表示できます。
実装例
新着にもランキングマークが出現するので通常の投稿リストで処理しても良いかも知れません。
カスタマイズ例
- 表示件数を増やしたい場合: $args['posts_per_page'] = 6;の部分を変更
- 表示する情報を増やしたい: ループの中に the_excerpt()やカテゴリの出力処理を追加
- 期間指定をもっと細かくしたい:「直近2週間」「直近30日」などのカスタマイズが可能です。'after' => '2 weeks ago'のように書くことで自由に指定できます。
配列の変更
通常は2列表示になっています。PCは3列、スマホは2列になるように設定可能です。
サイドバーは1列です。
下記のコードをCSSに追記してください。
.-w-ranking .p-postList {
  display: flex;
  flex-wrap: wrap; /* 子要素を折り返し可能に */
  gap: 20px;       /* カード同士の余白をつける */
}
/* 3カラム(PC) */
.-w-ranking .p-postList__item {
  flex: 1 1 calc(33.33% - 20px);
  box-sizing: border-box; /* 幅計算が崩れないように */
}
/* 幅960px以下(タブレット・スマホなど)で2カラム */
@media (max-width: 960px) {
  .-w-ranking .p-postList__item {
    flex: 1 1 calc(50% - 20px);
  }
}
/* サイドバー用(100%幅で1カラム) */
.l-sidebar .-w-ranking .p-postList__item {
  flex: 1 1 100%;
}まとめ
1つのショートコードで新着記事と期間ごとの人気記事を切り替えて表示できるので、とても便利です。期間を自由に変えられるため、サイトのトップやサイドバー、投稿下部など、さまざまな場所に応用できます。
もしPV数の計測や保存をまだしていない場合は、人気記事プラグインやテーマ独自のPV計測機能などを使ってメタキーに数値が保存されるように設定しておくとスムーズです。ぜひ活用してみてくださいね。

コメント