WordPressの年月日アーカイブページを弄っていて気付いたこと。

投稿のない年月日のページを指定したURLにアクセスすると、404ページの扱いになる。

まあ、間違ってはいないけど。

検索結果ページでは投稿が見つからない場合に404になったりはしない。

ということで今回は、投稿のない年月日アーカイブページを、404ページとは違う表示にしてみる。

アーカイブページの判定

年月日アーカイブページを表示させるには、date.php とか archive.php とか index.php といったテーマファイルを使うことになるのだが、投稿のない年月日アーカイブページとなると 404.php が(もしあれば)呼び出されることになる。

つまり、今回紹介するコードは 404.php か、なければ index.php に記述することになる。

その上で、 is_date() ……もまた使えない。

投稿がない場合 is_date()false になり、代わりに is_404()true になるためだ。

だから、URLが年月日アーカイブページを示している場合、その年月日を取得してから判定しなければならない。

どの年月日アーカイブページにも「年」の情報は存在するから、これを用いて判定することができる。

ただし、テーマファイルで is_404() を使って404ページを判定している場合、それより先に「年」の情報が存在するかどうかの判定をする必要がある。

年月日の取得

404ページであっても、URLが年月日アーカイブページを示すなら、メインクエリから年月日の情報を取得できる。

global $wp_query;
$year = (int) $wp_query->get('year', 0);
if ( $year > 1999 ) { // 数値はテキトー
    /* 年月日アーカイブページの場合 */
}

index.php のようなテーマファイルで他のアーカイブページとともに判定する場合、判定は他のアーカイブページより後、かつ404ページより先に行うこと。

そして、月と日の取得と判定は以下の通り。

$is_date = $is_year = $is_month = $is_day = false;
if ( $year > 1999 ) {
    $is_date = true;
    $monthnum = (int) $wp_query->get('monthnum', 0);
    if ( 0 < $monthnum && $monthnum < 13 ) {
        $day = (int) $wp_query->get('day', 0);
        if ( checkdate($monthnum, $day, $year) ) {
            // 日別アーカイブページの場合
            $is_day = true;
        } else {
            // 月別アーカイブページの場合
            $is_month = true;
        }
    } else {
        // 年別アーカイブページの場合
        $is_year = true;
    }
}

月の判定はいいとして、日の判定には chechdate() という便利な関数があるのでこれを使う。

さて、これで年月日の数値を取得できたし、 is_year() の代わりに使える $is_year やそれ関連の変数も設定できたし、あとは表示を考えるだけだ。

<?php if ( $is_year ) { ?>
<h2><?php printf('%d年%d月%d日の記事', $year, $monthnum, $day); ?></h2>
<p>該当の記事が見つかりませんでした。</p>
<?php } elseif ( $is_month ) { ?>
<!-- 中略 -->
<?php } elseif ( $is_day ) { ?>
<!-- 中略 -->
<?php } elseif ( is_404() ) { ?>
<h2>Not Found (404)</h2>
<p>ページが存在しません。</p>
<?php } ?>

青字がHTML緑字がPHP

ちなみに、投稿が存在しない過去の年月日ではなく、未来の年月日のURLを訪問した場合も同様になる。

未来の年月日であるかどうかを判定するには、以下のようにする。

<?php
$thisday = $year * 10000 + $monthnum * 100 + $day;
$today = (int) date('Ymd', time());
// サーバー時間の時差により日付がずれる場合は以下を使う。
// $today = (int) date('Ymd', time() + get_option('gmt_offset', 0) * 3600);
?>

<?php if ( $thisday > $today ) { ?>
<h2>すごーい!</h2>
<p>あなたは未来から来たフレンズなんだね!</p>
<?php } ?>

まとめ

内部的に404でなくなるわけではないが、以上のように「投稿の存在しないアーカイブページ」を404ページとは別の表示にすることができる。

他のサイトとの違いを見せつけたい場合におすすめ。

それと、俺は今期の深夜アニメは何も観ていません。