[WordPress General] Rewrite API を利用してカテゴリ毎の年次アーカイブのインデックスページを作成する
WordPress が用意していない独自の URL にアクセスしたときに、必要なアーカイブインデックスを表示するように設定します。
[markdown]
## 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/add rewrite rule – WordPress Codex 日本語版](https://wpdocs.osdn.jp/Rewrite_API/add_rewrite_rule)
リライトルールは、下記のプラグインなどで確認する事ができます。
> * [Rewrite Rules Inspector — WordPress プラグイン](https://ja.wordpress.org/plugins/rewrite-rules-inspector/)
Rewrite API については、こちらが大変参考になりました。
> * [Rewrite APIその1 「Rewriteとパーマリンク」(WordPressプラグイン開発のバイブルのボツ原稿から) – Shinichi Nishikawa’s](https://nskw-style.com/2014/wordpress/rewrite-permalink.html)
> * [Rewrite APIその2 WordPressでアプリを作る基本(WordPressプラグイン開発のバイブルのボツ原稿から) – Shinichi Nishikawa’s](https://nskw-style.com/2014/wordpress/wordpress-app-with-rewrite-api.html)
## 下準備
Twenty-Seventeen の子テーマを用意します。
細かい手順は省略します。
> * [子テーマ – WordPress Codex 日本語版](https://wpdocs.osdn.jp/%E5%AD%90%E3%83%86%E3%83%BC%E3%83%9E)
準備を終えると、ファイルレイアウトは下記のようになります。
“`prettyprinted
/wp-content/themes/twentyseventeen-child
├── functions.php
└── style.css
“`
## リライトルールの追加
WP_Query を参考にリクエストパラメータを組み立てます。
`year` と `category_name` にそれぞれの値を渡します。
> * [関数リファレンス/WP Query – WordPress Codex 日本語版](https://wpdocs.osdn.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/WP_Query)
さらにページネーション用にルールを追加します。
`paged` を渡します。
> * [url rewriting – add_rewrite_rule and pagination issue – WordPress Development Stack Exchange](https://wordpress.stackexchange.com/questions/18696/add-rewrite-rule-and-pagination-issue)
“`php:functions.php
/backnumber/
* 該当するカテゴリー&年別のアーカイブを表示する
*/
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`
> * [WordPressのフックで名前空間を使うときにハマらないために気をつけたいこと – WPJ](https://www.webprofessional.jp/understanding-namespaces-wordpress-hook-system/)
debug mode で開発しているときのみ `flush_rewrite_rules` を利用して、リライトルールの変更を自動で反映させます。
“`php
add_action(‘init’, ‘flush_rewrite_rules’);
“`
> * [関数リファレンス/flush rewrite rules – WordPress Codex 日本語版](https://wpdocs.osdn.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/flush_rewrite_rules)
> * [プラグイン API/アクションフック一覧 – WordPress Codex 日本語版](https://wpdocs.osdn.jp/%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3_API/%E3%82%A2%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%95%E3%83%83%E3%82%AF%E4%B8%80%E8%A6%A7)
memo.
> * [いい加減 flush_rewrite_rules を書くのはやめてください!! – Toro_Unit](https://torounit.com/blog/2015/09/02/2077/)
> * [WordPressに独自のURLを追加する。2014年版 | Firegoby](https://firegoby.jp/archives/5309)
## タイトルの調整
カテゴリー&年別のアーカイブのタイトルを整えます。
> * [Wordpressで指定したカテゴリーの年別アーカイブを作成する | webOpixel http://www.webopixel.net/wordpress/236.html の改造版。プラグイン有効時にflush_rules()か、パーマリンク設定の更新が必要。](https://gist.github.com/torounit/5106240)
但し wp_title は使われていないので、Hook を document_title_parts に変更します。
> * [document_title_parts | Hook | WordPress Developer Resources](https://developer.wordpress.org/reference/hooks/document_title_parts/)
“`php:functions.php
/**
* カテゴリー&年別のアーカイブのタイトルを整える
*/
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 );
“`
> * [関数リファレンス/is year – WordPress Codex 日本語版](https://wpdocs.osdn.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/is_year)
> * [関数リファレンス/get query var – WordPress Codex 日本語版](https://wpdocs.osdn.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/get_query_var)
## その他
その他、関連するトピックス。
### 変数を追加する
`&cat_slug=$matches[1]` などで渡された変数を追加する場合、下記のように `query_vars` へ登録する。
> * [WordPress Query Vars – WordPress Codex 日本語版](http://wpdocs.osdn.jp/WordPress_Query_Vars)
> * [カスタムクエリ – WordPress Codex 日本語版](https://wpdocs.osdn.jp/%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0%E3%82%AF%E3%82%A8%E3%83%AA)
“`php:functions.php
/**
* $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` を利用する。
> * [WordPressループ生成まとめ – メインクエリとサブクエリ | hijiriworld Web](http://hijiriworld.com/web/wp-query-standard/)
> * [プラグイン API/アクションフック一覧/pre get posts – WordPress Codex 日本語版](https://wpdocs.osdn.jp/%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3_API/%E3%82%A2%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%95%E3%83%83%E3%82%AF%E4%B8%80%E8%A6%A7/pre_get_posts)
“`php:functions.php
/**
* メインクエリの内容を変更する
*/
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’ );
“`
## 補遺
> * [[WordPress] wp get archives にないカテゴリ毎の月次アーカイブに対応する | deadwood](https://www.d-wood.com/blog/2014/08/27_6760.html)
[/markdown]