カスタム投稿のURLにカスタムタクソノミーのタームを含める方法
WordpressのURLにカスタムタクソノミーを含めることでURLの階層化を行う、WEBサイトの日本語版と英語版を作成したときのメモ。
目的
カスタム投稿ページにカスタムタクソノミーを作成し、その記事にタームがある、なし、でURLを書き換える。
たとえば、記事によって国を分けることを想定してFR、ENなどのタームを作成する
- カスタム投稿は「articles」という名前で作成する。
- カスタムタクソノミーは「articles-category」という名前で作成する。
- 記事にタームが何もなかった場合、日本語記事と判断しそのままのURLを使用する。
- 記事にタームENがついていた場合、英語記事と判断し、URLにENを含める。
結果
動作結果
一つのドメインで複数のWORDPRESSを1つのサブディレクトリにまとめている環境でURLの書き換えを実施する。
たとえば「https://sample.com」だった場合、こんな構成。
https://sample.com
│
└─site
├─AAA <--- サイトAAAのWordpressをインストール
└─BBB <--- サイトBBBのWordpressをインストール
トップページ
https://sample.com/site/AAA/
デフォルト(日本記事)
https://sample.com/site/AAA/articles/記事名
ENタームがついていたら(英語記事)
https://sample.com/site/AAA/en/articles/記事名
※URLの書き換えがドメイン配下を書き換えてしまうことで少しはまる。
ソース
▼カスタム投稿の作成
カスタム投稿の作り方は「WordPressでカスタム投稿タイプとメタボックスを使用して独自の投稿画面を作成する方法」を参照する。
▼カスタムタクソノミーの作成
カスタムタクソノミーは以下として作成する。
function custom_taxsonomy() {
$articleTar = array('articles');
$articleCat = array(
'label' => "国カテゴリー",
'show_admin_column' => true,
'public' => true,
'show_ui' => true,
'sort' => true,
);
register_taxonomy('articles-category',$articleTar,$articleCat);
}
▼function.php
/******************************************************/
/** URL REWRITE **/
/******************************************************/
add_filter( 'post_type_link', function( $permalink, $post, $leavename ) {
if ( $post->post_type == 'articles' ) {
$term = wp_get_post_terms( $post->ID, 'articles-category' )[0]->slug;
if ( $term) {
return esc_url( home_url( '/' )) . "/en/articles/" . $post->post_name . "/" ;
} else {
return $permalink ;
}
}
}, 10, 4 );
add_action( 'init', function() {
global $wp_rewrite;
add_rewrite_rule( 'en/articles/([^/]+)(/page/([0-9]+))?/?', 'index.php?articles=$matches[1]', 'top');
$wp_rewrite->flush_rules( false );
}
▼Wordpressの設定
方法
フロー
1カスタム投稿の作成 |
↓ |
2カスタムタクソノミーの作成 |
↓ |
3function.phpに記述追加 |
↓ |
4WordPressのパーマネントリンク設定変更 |
カスタム投稿の作成
カスタム投稿の作り方は「WordPressでカスタム投稿タイプとメタボックスを使用して独自の投稿画面を作成する方法」を参照する。
カスタムタクソノミーの作成
カスタムタクソノミーはカスタム投稿タイプ「articles」に表示する。
管理画面に表示するために「show_admin_column」を設定する。
タクソノミー名は「articles-category」としている。
function custom_taxsonomy() {
$articleTar = array('articles');
$articleCat = array(
'label' => "国カテゴリー",
'show_admin_column' => true,
'public' => true,
'show_ui' => true,
'sort' => true,
);
register_taxonomy('articles-category',$articleTar,$articleCat);
}
register_taxonomy()で設定している値
値 | 説明 |
---|---|
label | (文字列) (オプション) タクソノミーの複数形の名前。翻訳の対象。 |
show_admin_column | (真偽値) (オプション) true にすると、関連付けられた投稿タイプのテーブルにタクソノミーのカラムを自動生成します。 |
public | (真偽値) (オプション) true にすると、タクソノミーは(パブリックに)検索可能になります。 |
show_ui | (真偽値) (オプション) true にすると、タクソノミーを管理するためにデフォルトの UI を用意します。 |
sort | (真偽値) (オプション) true にすると、タクソノミーのタームがオブジェクトへ付けられた順序を記憶する。 |
function.phpに記述追加
まずURLの文字列を書き換える。下のコードはカスタム投稿「articles」の場合、タクソノミー「articles-category」を取得、値が存在していたらarticlesの前に英語記事を表す「en」がついたURLに書き換えている。
条件が当てはまらない場合は通常のパーマネントリンクを返す(return $permalink箇所)。
ここで「https://sample.com/site/AAA/en/articles/記事名」というURLに代わる。
add_filter( 'post_type_link', function( $permalink, $post, $leavename ) {
if ( $post->post_type == 'articles' ) {
$term = wp_get_post_terms( $post->ID, 'articles-category' )[0]->slug;
if ( $term) {
return esc_url( home_url( '/' )) . "/en/articles/" . $post->post_name . "/" ;
} else {
return $permalink ;
}
}
}, 10, 4 );
ここで少しはまる、以下だとドメイン直下に変更した文字列が付加されるため、サブディレクトリでは使えなかった
これでは「https://sample.com/en/articles/記事名」となってしまう。
home_url( '/' )を使うことで自分のホームURLを取得することで解決する。
return "/en/articles/" . $post->post_name . "/" ;
この状態ではURLは変わるがWordpressで任意のページを割り当ててくれない。そのためadd_rewrite_ruleでリライトする。
この時点で「en/articles」に代わっているため、その文字列を対象とする。
.htaccessを都度更新しないようにする。
add_action( 'init', function() {
global $wp_rewrite;
add_rewrite_rule( 'en/articles/([^/]+)(/page/([0-9]+))?/?', 'index.php?articles=$matches[1]', 'top');
$wp_rewrite->flush_rules( false ); # <--- .htaccessを都度更新しないようにする。
}
add_rewrite_rule()で設定している値
値 | 説明 |
---|---|
$regex | (文字列)(必須) リクエストされたURLにマッチする正規表現。オプションで1つ以上のグループを使用できる。 |
$redirect | (文字列) (必須) $regexがマッチした場合に、実際にフェッチしたいURL。マッチしたキャプチャグループを挿入するには $matches[] を使用する。 |
$after | (文字列) (オプション) 'top' または 'bottom'。'top' の場合、ルールは WordPressのすべての既存ルールに優先する。'bottom' の場合、ルールはすべての既存ルールがマッチしない場合に検査される。 |
WordPressのパーマネントリンク設定変更
WordPressのパーマネントリンクをデフォルト以外にしておく。
参考
その他詳細
register_post_type()のrewrite変数(カスタム投稿作成時)
カスタム投稿作成時のregister_post_type()の中でもrewriteを設定可能。以下のような
$sampleArray = array (
"labels" => $sampleLabels,
#・・・省略・・・
'rewrite' => array('slug' => 'parmarink'), # <--- parmarinkでリライトする
);
register_post_type('event' , $sampleArray);
これだと一律で「ドメイン/permarink/記事名」になるため、今回は採用しなかった。
リライトルールの確認方法
$wp_rewriteオブジェクトの中からリライトルールを確認することができる。
<?php
echo '<pre>';
var_dump( $wp_rewrite );
echo '</pre>';
?>
# ↓こんな感じで格納されている
# ・・・省略・・・
["^index.php/wp-json/(.*)?"]=>
string(33) "index.php?rest_route=/$matches[1]"
["en/articles/([^/]+)(/page/([0-9]+))?/?"]=>
string(30) "index.php?articles=$matches[1]"
# ・・・省略・・・