[WordPress General] Rewrite API を利用してカテゴリ毎の年次アーカイブのインデックスページを作成する
WordPress が用意していない独自の URL にアクセスしたときに、必要なアーカイブインデックスを表示するように設定します。
Contents
WordPress のリクエスト処理の流れ
リクエストパラメータに基づいて処理を行い、その結果を返します。
http://vccw.local/index.php?p=123
のようにリクエストパラメータをクエリ文字列として受け取る。- リクエストパラメータは
$wp->query_vars
に格納される($wp
はグローバル変数)。
URLのリライトとルールの追加
設定>パーマリンク設定
でリライト機能を有効にすると、http://vccw.local/2017/12/04/sample-post/
のようにURLからリクエストパラメータを取得することができます。
また add_rewrite_rule()
を利用すると、追加でリライトルールを指定できます。
リライトルールは、下記のプラグインなどで確認する事ができます。
Rewrite API については、こちらが大変参考になりました。
下準備
Twenty-Seventeen の子テーマを用意します。
細かい手順は省略します。
- 子テーマ – WordPress Codex 日本語版
準備を終えると、ファイルレイアウトは下記のようになります。
/wp-content/themes/twentyseventeen-child
├── functions.php
└── style.css
リライトルールの追加
WP_Query を参考にリクエストパラメータを組み立てます。
year
と category_name
にそれぞれの値を渡します。
さらにページネーション用にルールを追加します。
paged
を渡します。
<?php
namespace Foo\Theme;
if ( WP_DEBUG ) {
add_action( 'init', 'flush_rewrite_rules' );
}
const CAT_BACKNUMS = 'feature|media|news';
/**
* /<category_name>/backnumber/<year> というリクエストがあった時に、
* 該当するカテゴリー&年別のアーカイブを表示する
*/
function add_back_number_rewrite_rule() {
$regex_1 = '^(' . CAT_BACKNUMS . ')/backnumber/([0-9]{4})$/?';
add_rewrite_rule(
$regex_1,
'index.php?year=$matches[2]&category_name=$matches[1]',
'top'
);
$regex_2 = '^(' . CAT_BACKNUMS . ')/backnumber/([0-9]{4})/page/([0-9]{1,})/?';
add_rewrite_rule(
$regex_2,
'index.php?year=$matches[2]&category_name=$matches[1]&paged=$matches[3]',
'top'
);
}
add_action( 'init', 'Foo\Theme\add_back_number_rewrite_rule' );
リライトルールは、先に書いた定義が優先されます。
またリライトルールの変更は、設定>パーマリンク設定>変更を保存
を実行することで反映されます。
補足
namespace
debug mode で開発しているときのみ flush_rewrite_rules
を利用して、リライトルールの変更を自動で反映させます。
add_action('init', 'flush_rewrite_rules');
memo.
タイトルの調整
カテゴリー&年別のアーカイブのタイトルを整えます。
但し wp_title は使われていないので、Hook を document_title_parts に変更します。
/**
* カテゴリー&年別のアーカイブのタイトルを整える
*/
function extend_year_wp_title( $title ) {
if ( is_year() && ! empty( get_query_var( 'category_name' ) ) ) {
$cat_year = get_query_var( 'year' );
$title['title'] = $title['title'] . ' : ' . $cat_year;
}
return $title;
}
add_filter( 'document_title_parts', 'Foo\Theme\extend_year_wp_title', 100, 1 );
その他
その他、関連するトピックス。
変数を追加する
&cat_slug=$matches[1]
などで渡された変数を追加する場合、下記のように query_vars
へ登録する。
/**
* $wp_query->query_vars にパラメータを追加する
*/
function add_back_number_to_qvar( $vars ) {
array_push( $vars, 'cat_slug' );
return $vars;
}
add_filter( 'query_vars', 'Foo\Theme\add_back_number_to_qvar' );
メインクエリを変更する
テンプレートを用意して new WP_Query
するのではなく、pre_get_posts
を利用する。
/**
* メインクエリの内容を変更する
*/
function modify_main_query( $query ) {
/* 管理画面 or メインクエリでない場合は何もしない */
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
/* 年別アーカイブページの場合 */
if ( $query->is_year() ) {
// 前述の通り、本来このようにする必要はない
$cat_slug = $query->query_vars['cat_slug'];
$query->set( 'category_name', $cat_slug );
return;
}
/* ホームページの場合 */
if ( $query->is_home() ) {
$query->set( 'posts_per_page', '3' );
return;
}
}
add_action( 'pre_get_posts', 'Foo\Theme\modify_main_query' );