CJコラム

【WordPress】WP_Queryを使って投稿を年度別に表示する(サンプルあり)

企業のIRサイトや教育系のサイトでは、「記事を4月始まりの年度別で一覧表示したい」というケースがたまにあります。
WordPressで年別に記事を表示しようとすると1月〜12月のくくりになってしまうので、WP_Queryを使って4月〜翌年3月などの年度別に投稿を表示する方法を考えてみました。

ページの仕様

今から作るページの概要はこちらです。

・通常のループではなくWP_Queryを使用
・アーカイブページは使わず、フロントページや固定ページ上に作成
・URLに年度のパラメータを追加します。ここでは、「http://example.com/news/?y=2018」のようなURLを想定
・URLに年度のパラメータがない場合、全ての年度の記事を表示

完成版コード

説明はいいからコードが見たい!という方はこちら。

 

▼記事一覧の表示

$y = $_GET['y'];
$m = 4; // 年度の開始月

// ループ設定
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args = array(
    'post_type' => '【投稿タイプ】',
    'posts_per_page' => 10,
    'paged' => $paged,
);
if($y){
    $args['date_query'] = array(
        'after'    => array(
            'year'  => $y,
            'month' => $m - 1,
        ),
        'before'    => array(
            'year'  => $y + 1,
            'month' => $m,
        ),
    );
}

// ループ設定
$fiscal_year = new WP_Query($args);
if($fiscal_year -> have_posts()):
    echo '<ul class="newsList">';
    while ($fiscal_year->have_posts()): $fiscal_year->the_post();
        //ここにループの内容
    endwhile;
else:
    echo '投稿はまだありません。';
endif;
wp_reset_postdata();

// ページャー
$big = 999999999;
echo paginate_links(array(
    'base' => str_replace($big, '%#%', esc_url(get_pagenum_link($big))),
    'format' => '?paged=%#%',
    'current' => max(1, get_query_var('paged')),
    'total' => $fiscal_year->max_num_pages
));

 

▼年度切り替えナビ

// 一番古い投稿を取得
$args_oldest_post = array(
    'post_type' => '【投稿タイプ】',
    'posts_per_page' => 1,
    'order' => 'ASC',
    'orderby' => 'date',
);
$oldest_post = new WP_Query($args_oldest_post);
if($oldest_post -> have_posts()):
    while ($oldest_post->have_posts()): $oldest_post->the_post();
        // 一番古い投稿の年、月を取得
        $oldest_post_y = get_the_date('Y');
        $oldest_post_m = get_the_date('n');
    endwhile;
endif;
wp_reset_postdata();

// ナビの開始年を設定
if($m > $oldest_post_m){
    $start = $oldest_post_y - 1;
} else{
    $start = $oldest_post_y;
}
// 現在の年、月を取得
$endYear = date('Y');
$endMonth = date('n');
// ナビの終了年を設定
if($m <= $endMonth){
    $end = date('Y');
} else{
    $end = date('Y') - 1;
}

// ナビを出力
echo '<ul class="nav">';
for ($i = $start; $i <= $end; $i++) {
    echo '<li><a href="/news/?y='.$i.'">'.$i.'</a><li>';
}
echo '</ul>';

 

何をやっているか説明

$y = $_GET['y'];
$m = 4; //年度の開始月

「http://example.com/news/?y=2018」というURLの場合、$yに2018を格納します。$mでは年度の開始月を設定しています。

$args = array(
    'post_type' => '【投稿タイプ】',
    'posts_per_page' => 10,
    'paged' => $paged,
);

$pagedはページャーを使うときの設定です。不要な場合は消して大丈夫です。
$args内はWordPress Codexなどを参考にしつつお好みで変更してください。

if($y){
    $args['date_query'] = array(
        'after'    => array(
            'year'  => $y,
            'month' => $m - 1,
        ),
        'before'    => array(
            'year'  => $y + 1,
            'month' => $m,
        ),
    );
}

URLに年度のパラメータが設定されている場合、年度での絞り込み条件を追加します。
「’after’の年月以降、’before’の年月までの投稿だけを表示する」という意味。
年度のパラメータがなければ、全投稿を表示します。

年度を切り替えるナビを作成

超簡易的ですが、一番古い投稿〜現在までの年のナビを作ります。

// 一番古い投稿を取得
$args_oldest_post = array(
    'post_type' => '【投稿タイプ】',
    'posts_per_page' => 1,
    'order' => 'ASC',
    'orderby' => 'date',
);
$oldest_post = new WP_Query($args_oldest_post);
if($oldest_post -> have_posts()):
    while ($oldest_post->have_posts()): $oldest_post->the_post();
        // 一番古い投稿の年、月を取得
        $oldest_post_y = get_the_date('Y');
        $oldest_post_m = get_the_date('n');
    endwhile;
endif;
wp_reset_postdata();

// ナビの開始年を設定
if($m > $oldest_post_m){
    $start = $oldest_post_y - 1;
} else{
    $start = $oldest_post_y;
}
// 現在の年、月を取得
$endYear = date('Y');
$endMonth = date('n');
// ナビの終了年を設定
if($m <= $endMonth){
    $end = date('Y');
} else{
    $end = date('Y') - 1;
}

// ナビを出力
echo '<ul class="nav">';
for ($i = $start; $i <= $end; $i++) {
    echo '<li><a href="/news/?y='.$i.'">'.$i.'</a><li>';
}
echo '</ul>';

新しいループを作成して、一番古い投稿を1件取得します。
一番古い投稿の年、月を取得して、そこからナビが始まるようにします。
(例)期が4月始まりで一番古い投稿が2018年2月にあった場合、この投稿は2017年度の投稿に分類されるので、ナビは2017年から始まります。
出力部分はお好みのHTMLに書き換えてください。

サンプルではナビの終わりを現在にしていますが、同じ要領で最新の投稿を取得すれば、もっとスマートなナビができます。

さいごに

いろいろ考えたので疲れました…。WordPressに標準でこの機能があればいいのに…。
せっかく作ったので、有効活用できたらいいなと思います!

最新5件の記事