カスタム投稿タイプでURL構造を親・子・孫にする
板橋区で日々、WordPress構築をがんばっているスタジオカッツェの竹上です。
この記事はWordPressの技術者向け記事です。
カスタム投稿タイプを使っている時に、カスタム投稿タイプ名/ターム名/記事名or記事ID というURL構造にしたい場合があります。
ソースからどうぞ。
カスタムタクソノミー名を入れずに、カスタム投稿タイプ/ターム名/記事スラッグ を実装する方法
functions.phpに以下を記述します。
// カスタム投稿タイプの登録
$news_args = array(
'labels' => array( 'name' => 'ニュース' ) , //「ニュース」の箇所は、任意のカスタム投稿タイプを入力してください
'public' => true,
'has_archive' => true,
"hierarchical" => true,
'with_front' => false,
'supports' => array(
'title',
'editor',
'thumbnail',
'custom-fields', //このあたりも、必要なものを入力してください
)
);
register_post_type( apply_filters( 'news_post_type', 'news' ), apply_filters( 'news_post_type_args', $news_args ) );
// カスタム投稿タイプのタクソノミー登録
add_action( 'init', 'news_taxonomies', 0 );
function news_taxonomies() {
register_taxonomy(
'news_cate',//タクソノミー名(英語)を記載します
array("news"),//カスタム投稿タイプ名を記載します
array( 'hierarchical' => true,
'label' => 'ニュースカテゴリ',//タクソノミー名を記載します
'query_var' => true,
'rewrite' => array(
'slug' => 'news', //URLでnews_cateと表記されるのをnewsに変更します。必要に応じて変更してください
'hierarchical' => true, //true にすると階層化したURLを使用可能にすます
'with_front' => false
),
)
);
}
//https://wordpress.stackexchange.com/questions/39500/how-to-create-a-permalink-structure-with-custom-taxonomies-and-custom-post-types
function vk_query_vars($qvars){
if(is_admin()) return $qvars;
$custom_taxonomy = 'news_cate'; //カスタムタクソノミー名を入れます
if(array_key_exists($custom_taxonomy, $qvars)){
$custom_post_type = 'news'; //カスタム投稿タイプ名を入れます
$pathParts = explode('/', $qvars[$custom_taxonomy]);
$numParts = sizeof($pathParts);
$lastPart = array_pop($pathParts);
$post = get_page_by_path($lastPart, OBJECT, $custom_post_type);
if( $post && !is_wp_error($post) ){
$qvars['p'] = $post->ID;
$qvars['post_type'] = $custom_post_type;
}
}
return $qvars;
}
add_filter('request', 'vk_query_vars');
//https://themoonwatch.com/en/2012/custom-permalinks-hierarchical-taxonomies/#sthash.6UaovMFc.i0ziCUO8.dpbs
add_action( 'generate_rewrite_rules', 'register_news_rewrite_rules' );
function register_news_rewrite_rules( $wp_rewrite ) {
$new_rules = array(
///news直下
'news/([^/]+)/?$' => 'index.php?post_type=news&news_cate=' . $wp_rewrite->preg_index(1) ,
'news/page/(\d{1,})/?$' => 'index.php?post_type=news&paged=' . $wp_rewrite->preg_index(1),
//親
'news/([^/]+)/([^/]+)/?$' => 'index.php?post_type=news&news_cate=' . $wp_rewrite->preg_index(1) . '&news_cate=' . $wp_rewrite->preg_index(2) ,
'news/([^/]+)/page/(\d{1,})/?$' => 'index.php?post_type=news&news_cate=' . $wp_rewrite->preg_index(1). '&paged=' . $wp_rewrite->preg_index(2),
//子
'news/([^/]+)/([^/]+)/page/(\d{1,})/?$' => 'index.php?post_type=news&news_cate=' . $wp_rewrite->preg_index(1) .'&news_cate=' . $wp_rewrite->preg_index(2) . '&paged=' . $wp_rewrite->preg_index(3),
'news/([^/]+)/([^/]+)/([^/]+)/?$' => 'index.php?post_type=news&news_cate=' . $wp_rewrite->preg_index(1) .'&news_cate=' . $wp_rewrite->preg_index(2) .'&news_cate='.$wp_rewrite->preg_index(3) ,
//孫
'news/([^/]+)/([^/]+)/([^/]+)/?$' => 'index.php?post_type=news&news_cate=' . $wp_rewrite->preg_index(1) . '&news_cate=' . $wp_rewrite->preg_index(2). '&news_cate=' . $wp_rewrite->preg_index(3),
'news/([^/]+)/([^/]+)/([^/]+)/page/(\d{1,})/?$' => 'index.php?post_type=news&news_cate=' . $wp_rewrite->preg_index(1) .'&news_cate=' . $wp_rewrite->preg_index(2) .'&news_cate=' . $wp_rewrite->preg_index(3) . '&paged=' . $wp_rewrite->preg_index(4),
'news/([^/]+)/([^/]+)/([^/]+)/([^/]+)/?$' => 'index.php?post_type=news&news_cate=' . $wp_rewrite->preg_index(1) .'&news_cate=' . $wp_rewrite->preg_index(2) .'&news_cate='.$wp_rewrite->preg_index(3) . '&news_cate=' .$wp_rewrite->preg_index(4),
//以下、階層の深さに合わせて、子・孫を参考に、$wp_rewrite->preg_index(n)の数を増やします
);
$wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
}
カスタム投稿タイプ、タクソノミーの設定は、Custom Post Type UIではうまくいかなかったので、functions.phpに直接記載しています。
Custom Post Type Permalinksの設定
その上で、Custom Post Type Permalinksをインストール、パーマリンクの設定を「/%news_cate%/%postname%/」にし、「カスタム分類のアーカイブのパーマリンクを変更する」のチェックを外して、「変更を保存」をクリックします。
「%postname%」の箇所はpost_idにしたい場合は、functions.phpの
'news/([^/]+)/?$'
の「([^/]+)」箇所を、
news/(\d{1,})/?$
のように、「(\d{1,})」にすれば行けます。正規表現の問題ですね。
パンくずの設定
Breadcrumb NavXTで、下記のようにすれば、ターム一覧、記事ページでも、意図(URL構造)通りのパンくずが実装出来ました。
カスタム投稿タイプのURL構造
設定方法を先に書いたので、以下、説明です。
WordPress構築において、カスタム投稿タイプ・カスタムタクソノミーの対応は必須になってくると思います。が、難点なのが、URL構造が「うまくいかない」こと。
Custom Post Type UIなどで設定すると、デフォルトでは
・カスタム投稿タイプ 一覧:/カスタム投稿タイプ名/
・カスタムタクソノミー 一覧:/カスタムタクソノミー名/カスタムターム名/
・記事:/カスタム投稿タイプ名/記事スラッグ
となります。
たとえば
・カスタム投稿タイプ名:ニュース(news)
・カスタムタクソノミー名:ニュースカテゴリ(news_cate)
・カスタムターム名:経済(economy)、エンタメ(entertainment)、スポーツ(sports)、国内(domestic)IT(it)
なら、
・カスタム投稿タイプ 一覧:/news/
・カスタムタクソノミー 一覧:/news_cate/economy/
・記事:/news/test-entry01
となります。サイトの運営方針にもよるかもしれませんが、URL構造として綺麗だし、直感的なので理想としては
・カスタム投稿タイプ 一覧:/news/
・カスタムタクソノミー 一覧:/news/economy/
・記事:/news/economy/test-entry01
となって欲しいですよね。
Custom Post Type Permalinksでカスタム投稿タイプのパーマリンク変更をしても。。。
Custom Post Type Permalinks を使うと、URL構造の変更が簡単にできます。
設定 > パーマリンク設定 > 「Permalink Settings for Custom Post Types」
で下の画像のように変更したいカスタム投稿タイプのパーマリンク設定を「/%news_cate%/%postname%/ 」と入力、「カスタム分類のアーカイブのパーマリンクを変更する」にチェックを入れれば、
・カスタム投稿タイプ 一覧:/news/
・カスタムタクソノミー 一覧:/news/news_cate/test-c01/
・記事:/news/economy/test-entry01
となります。これでもやっぱりカスタムタクソノミー 一覧の「/news_cate」がちょっと「ごめん、君いらないんだけど。。。」感があります。しかも「/news/news_cate/」にアクセスしても、404になります。さみしい。
これ、どうにもならないモノだとばかり思っていました。
カスタム投稿タイプのURL構造を変更するのに参考にしたサイト
下記2サイトを参考にさせて頂いたのですが、タームに親・子・孫がうまくいかない。。。
WordPressでタクソノミー(カスタム分類)を省略したパーマリンクに変更する方法!
【SEOを考慮したWordPressサイト構築】3/3 STEP3 カスタム投稿タイプURLの設定方法
ところが、泣きながら海外のサイトを調べていると、以下の2記事を見つけました。特に後者はまさかの2012年の記事なのですが、これがドンピシャでした。
Custom Permalinks for hierarchical taxonomies / Moon Watch
タイトル(記事名もしくはターム名 – サイト名)、パンくず(URL構造通りに出力される)、ページング(Breadcrumb NavXTで検証、2ページ目以降も表示される)、All in One SEOでのxmlの出力も、ひととおり問題なかったので、おそらく大丈夫だとは思いますが、実装される際は自己責任でお願いします。もし何か不具合等あれば、ご指摘頂ければ大変嬉しいのですが、ご対応できない場合もありますのでご容赦ください。
WordPressでお困りですか?
WordPressのテーマ構築、カスタマイズなど、スタジオカッツェにご相談ください。
個人事業主様、Web制作会社様からのご相談をお待ちしております。