こんにちは、コバヤシです。
今回はWordPressの投稿ページのパーマリンクにカスタムフィールドの値を使用する方法について書きます。
よくある方法
今回は、/hogehoge/【カスタムフィールドで設定した値】で投稿ページを表示したいと思います。
(カスタムフィールドのフィールド名はcodeとします)
ネットで検索すると見つかるのが、以下の方法です。
functions.php
<?php function custom_rewrite_rule() { add_rewrite_rule( '^hogehoge/([0-9]+)/?$', 'index.php?post_type=xxxxx&code=$matches[1]', 'top' ); } add_action('init', 'custom_rewrite_rule'); function custom_query_vars($vars) { // コードをGETで読めるように設定 $vars[] = 'code'; return $vars; } add_filter('query_vars', 'custom_query_vars'); function custom_template_include($template) { // コードがあったら指定した投稿ページのテンプレートファイルを読み込むようにする if (get_query_var('code')) { $include_template = locate_template(['hoge.php']); if (!empty($include_template)) { return $include_template; } } return $template; } add_filter('template_include', 'custom_template_include'); function custom_pre_get_posts( $query ) { if ( ! is_admin() && $query->is_main_query() ) { // codeがあったらカスタムフィールドの値を条件に取得するようにする if ( get_query_var('code')) { $query->set( 'meta_key', 'code' ); $query->set( 'meta_value', get_query_var('code') ); } } } return; } add_action( 'pre_get_posts', 'custom_pre_get_posts' );
add_rewrite_ruleで、マッチしたコードをGET値として渡して、そのGETの値があったら、クエリの条件の追加と呼び出すテンプレートファイルの変更を行っています。
上記の方法の問題点
上記の方法でも詳細画面は表示されますが、問題があります。
それは、WordPress的にはこのページはアーカイブページとして認識されているということです。
All in One SEOで設定された内容が反映されず、そのままではアーカイブ用のタイトルなどが表示されてしまいます。
functions.phpでフックを書けば変更できますが、All in One SEOの設定画面で入力した値をそのまま使いたい。。。
解決方法
試行錯誤の結果、以下の方法で解決できました。
functions.php
<?php function custom_rewrite_rule() { add_rewrite_rule( '^hogehoge/([0-9]+)/?$', 'index.php?post_type=xxxxx&code=$matches[1]&p=1', 'top' ); } function custom_pre_get_posts( $query ) { if (! is_admin() && $query->is_main_query()) { // codeがあったらカスタムフィールドの値を条件に取得するようにする if (get_query_var('code')) { $query->set( 'meta_key', 'code' ); $query->set( 'meta_value', get_query_var('code') ); $query->set('p', null); // post_idによる検索を削除 } } return; } add_action( 'pre_get_posts', 'custom_pre_get_posts' );
ミソはadd_rewrite_ruleのURLにP=1を付けることと、pre_get_postsでp(post_id)による条件検索を削除することです。
p=1を付けることでWordPressに投稿ページのアクセスとして認識させることができるので、後はpre_get_postsでpost_idで検索しないように削除してあげるだけでOKです。
WordPress的に投稿ページとして認識されているので、template_includeのフィルターで読み込むテンプレートを変更する必要もありません。
まとめ
書いてしまうと簡単なことですが、この方法にたどり着くまでに少し時間を要しました。
WordPressはちょっとしたカスタマイズのつもりが、手がかかることが多々あります。
しかし、その分だけ理解が深まり、より柔軟なサイト構築が可能になります。
これからも様々なカスタマイズに挑戦し、知識を付けていきたいと思います。