WordPressの記事のURL(パーマリンク設定)を投稿名(%postname%)にしている人が多いと思います。
投稿名にすると、日本語のタイトルがURLに入って好ましくないので、いちいち英語に直している人も多いと思います。
SEO的にはその方がいいのですが、記事の数が増えると面倒になってきます。
だったら最初からpost_idを使ってslugを設定すればいいよね、という話があります。
slugにpost_idを自動的に設定するスニペット
記事の保存時にスニペットでslugを設定することができます。その時に、post_idを使ってslugを設定します。
この方法は、パーマリンク設定が投稿名(%postname%)になっている必要があります。
/* 投稿記事のスラッグを「blog-ID」で採番 */
function custom_auto_post_slug( $slug, $post_ID, $post_status, $post_type ) {
if ( $post_type == 'post' ) {
$slug = utf8_uri_encode( 'post' ) . '-' . $post_ID;
}
return $slug;
}
add_filter( 'wp_unique_post_slug', 'custom_auto_post_slug', 10, 4 );
最初は良いのですが、slugが書き換わってしまうので、記事が増えてくると後からslugを他のものに変更するのが大変じゃないか?と不安になる人は多いかもしれません。
確かに、もし、”post-“の部分を変更したくなると、全ての記事をもう一度更新する必要があります。
パーマリンク設定だけでpost_idのURLに変えられないか?
複雑なことをしなくても、パーマリンクをpost_idに変更できます。
パーマリンクをカスタム構造にして、”post-“%post_id%と設定すれば、slugによらず、投稿の記事はそのパーマリンクになります。
しかし、この方法は問題があります。
カテゴリやタグ、月別アーカイブの名前も変わってしまうことです。
URLのカテゴリは”post-category”、タグは”post-tag”、月別アーカイブは”post-date”となってしまいます。
これを避けるには、カテゴリベースやタグベースをそれぞれ最初の値に設定してあげれば元に戻ります。
しかし、月別アーカイブはオプションからベースを変更できないので、”post-date”のままになってしまう欠点があります。
まぁ、ものすごく変なわけでもないですし、大事なページでもないので、気にしなければ気にしないでいい話かと思います。
投稿だけパーマリンク設定を限定するには?
WordPressのパーマリンク変更をパーマリンク設定を介さずに行うには、以下の2つが必要です。
- 記事のURL出力を所望のパーマリンク構造に合わせてカスタマイズする
- カスタマイズした記事URLをリライトルールでリダイレクトする
パーマリンク設定を無難な投稿名にしておいて、投稿のパーマリンクは関数を使って好き勝手に変えることができます。
そうすれば、カテゴリやタグ、月別アーカイブなどに変な文字列は追加されません。
投稿のパーマリンクを『post-%post_id%』というパーマリンクにするコードになります。
<?php
function add_article_post_permalink( $permalink ) {
$custom_prefix="post";
$permalink = '/'.$custom_prefix.'-%post_id%/';
return $permalink;
}
add_filter( 'pre_post_link', 'add_article_post_permalink' );
function add_my_leaf_rewrite ( $rules ) {
$custom_prefix="post";
//追加するリライトルールの配列を初期化
$new_rules = array();
//追加するリライトルールの配列を作成
$new_rules['^'.$custom_prefix.'-([0-9]+)/?'] = 'index.php?p=$matches[1]';
//既存のリライトルールに作成した配列を追加
return $new_rules + $rules;
//または return array_merge ($new_rules, $rules);
}
add_filter('rewrite_rules_array', 'add_my_leaf_rewrite');
pre_post_linkフックの$permalinkはパーマリンク設定の文字列になりますので、決め打ちします。
記事のURLは『post-%post_id%』というルールで出力されるようになるので、あとはそのURLをリライトしてあげればいいです。
以下のスニペットでWordpressが内部に保持しているリライトルールを流用して設定することができます。
$queryはクエリパラメータのURLなので変更ありません。変更しなければならないのは正規表現の部分をパーマリンクに対応させる必要があります。
自分で書くのが面倒ということであれば、パーマリンク設定に%post_id%を設定しておけば、%post_id%の正規表現を流用できます。
function add_leaf_post_rewrite_rules( $rewrite_rules ) {
$custom_prefix="post";
//カスタマイズするルールの配列の初期化
$my_rules = array();
//投稿のルールの配列 $rewrite_rules の要素を foreach()で処理
foreach ( $rewrite_rules as $regex => $query ) {
//要素のキー(正規表現パターン)に $custom_prefix- を追加した値を指定。
$my_rules[$custom_prefix.'-' . $regex] = $query;
}
//正規表現パターンに $custom_prefix- を追加した配列をルールとして戻す
return $my_rules;
}
add_filter( 'post_rewrite_rules', 'add_leaf_post_rewrite_rules' );
注意点としては、正規表現部分にグループ化で()を追加してしまうと、$queryのmatchの添え字と対応が取れなくなるので、グループ化する時には(?: )で囲んでmatchしないようにする必要がある
まとめ
WordPressのパーマリンクのカスタマイズは失敗するとページが表示されなくなるのであまりさわりたくないのですが、slugにpost_idを入れるのが嫌なので今回のようなカスタマイズが必要になりました。