カスタム投稿のパーマリンクからカスタムタクソノミーの子孫タームを削除する
この記事は2019年10月14日に書かれたものです。情報が古い可能性がありますのでご注意ください。
カスタム投稿タイプのパーマリンク設定でカスタムタクソノミーを含めた場合、そのタクソノミータームに親子関係があると、それが階層的に設定されます。
- パーマリンク設定
- https://www.example.com/custom-post-slug/%custom_taxonomy_slug%/%postname%/
- 親タームがあるときの URL
- https://www.example.com/custom-post-slug/親ターム/子ターム/投稿名/
今回、URL から子孫タームは削除して親タームのみとしたい案件があり、ググってみると、投稿のパーマリンクでカテゴリを含めた場合に子カテゴリを削除する方法はいくつか見つかりましたが、カスタムタクソノミーの例は見つからず、試行錯誤してみました。
投稿のカテゴリの場合は、以下のようなコードを functions.php に追加すると親カテゴリーのみのURLとすることができるようです。
function remove_children_category_slug( $permalink, $post, $leavename ){
//カテゴリのIDを取得
$cats = get_the_category( $post->ID );
if ( $cats ) {
//ID順にソート
usort( $cats, '_usort_terms_by_ID' );
foreach( $cats as $cat ) {
//親カテゴリが存在するかチェック
if ( $cat->parent ) {
$parentcategory = explode(" ",get_category_parents( $cat, false, ' ', true ));
//配列から最上位のカテゴリを取得
$parentcat = $parentcategory[0];
} else {
//親がない場合はそのままスラッグを取得
$parentcat = $cat->slug;
}
}
}
//管理画面で設定したパーマリンクの設定に合わせる
$permalink = home_url().'/'.$parentcat.'/'.$post->post_name . '/';
return $permalink;
}
add_filter( 'post_link', 'remove_children_category_slug', 10, 3 );
これを元に、試行錯誤した結果、以下のような感じで親タームのみの URL とすることができました。
function remove_children_term_slug( $permalink, $post, $leavename ){
// 適用する投稿タイプ
if ( $post->post_type === 'custom-post-slug' ){
//タームのIDを取得
$terms = get_the_terms( $post->ID, 'taxonomy-slug' );
if ( $terms ) {
//ID順にソート
wp_list_sort( $terms, 'term_id' );
foreach( $terms as $term ) {
//親タームが存在するかチェック
if ( $term -> parent ) {
//配列から最上位のタームを取得
$term = array_shift($terms);
}
$parent_term = $term->slug;
}
}
//管理画面で設定したパーマリンクの設定に合わせる
$permalink = home_url().'/custom-post-slug/'.$parent_term.'/'.$post->post_name.'/';
}
return $permalink;
}
add_filter( 'post_type_link', 'remove_children_term_slug', 10, 3 );
カテゴリのIDを取得する get_the_category に対して、タームのIDを取得するため get_the_terms を使用しますが、ID順にソートする方法、配列から最上位のタームを取得する方法が、カテゴリの例のようにするとエラーを吐き出すので悩みましたが、結果的にシンプルになったような気がします。
(2020年1月10日一部修正)
特定の投稿タイプにのみ設定するための条件分岐を追加しました。
“カスタム投稿のパーマリンクからカスタムタクソノミーの子孫タームを削除する”への 2 件のコメント
hanaさんより:
いくつかカスタム投稿を作成しており、特定の投稿タイプだけ親タームのみURLに表示させたかったので、
こちらの記事を参考にさせていただきました。
こちらの記事のままだとすべてのカスタム投稿に適用されてしまいます。
特定のカスタム投稿のみにするには、if( $post->post_type === '{投稿タイプ}' )というように
条件分岐で囲ったらいいのかと思ったのですが、そうすると他の投稿タイプではパーマリンクが
設定されない状態になってしまいます。
特定の投稿タイプのみにこのフィルターを使うにはどのようにすれば良いでしょうか?
アドバイスいただけると嬉しいです。よろしくお願いいたします。
石輪さんより:
条件分岐で囲む範囲は正しいでしょうか?
上記のコードに、特定の投稿タイプにのみ設定するための条件分岐を追加しましたので、参考にしてみてください。