カスタム投稿タイプで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年の記事なのですが、これがドンピシャでした。

How to create a permalink structure with custom taxonomies and custom post types like base-name/parent-tax/child-tax/custom-post-type-name – WordPress Development Stack Exchange

Custom Permalinks for hierarchical taxonomies / Moon Watch

タイトル(記事名もしくはターム名 – サイト名)、パンくず(URL構造通りに出力される)、ページング(Breadcrumb NavXTで検証、2ページ目以降も表示される)、All in One SEOでのxmlの出力も、ひととおり問題なかったので、おそらく大丈夫だとは思いますが、実装される際は自己責任でお願いします。もし何か不具合等あれば、ご指摘頂ければ大変嬉しいのですが、ご対応できない場合もありますのでご容赦ください。

Leave a Comment