パーマリンク付きのネストされたカスタム投稿タイプ


9

authors/books/chapters著者、本、章がすべて独自のカスタム投稿タイプとして設定された、のようなパーマリンクを含むマルチレベルのカスタム投稿タイプ構造を設定しようとしています。たとえば、このサイトの一般的なURLは次のようになります。example.com/authors/stephen-king/the-shining/chapter-3/

各章は1つの本にのみ属することができ、各本は1人の著者にのみ属することができます。著者と本のCPTの代わりに分類法を使用することを検討しましたが、メタデータを各アイテムに関連付ける必要があり、これにはポストインターフェイスを使用します。

私は、CPTのエントリの子として各カスタム投稿を1レベル上に設定するだけで、ほとんどの方法を実行できます。たとえば、「Chapter 3」を作成し、カスタムメタボックスを使用して「The Shining」を親として割り当てます。「The Shining」は、「Stephen King」を親として持っています。私はこれらの関係を作成するのに何の問題もありませんでした。

CPTスラグで書き換えタグを使用していて、パーマリンクが機能したいのですが、それらは完全に正しくありません。書き換えアナライザーを使用すると、書き換えルールが実際に生成されていることがわかりますが、それらのルールは正しい順序になっていないため、他のルールが最初に処理されます。

これが私の書き換えアナライザーのスクリーンショットです。

CPTの登録方法は次のとおりです。

function cpt_init() {

  $labels = array(
    'name' => 'Authors'
   );

  $args = array(
    'labels' => $labels,
    'public' => true,
    'publicly_queryable' => true,
    'show_ui' => true, 
    'show_in_menu' => true, 
    'query_var' => true,
    'rewrite' => array(
        'slug' => 'author',
        'with_front' => FALSE,
    ),
    'with_front' => false,
    'capability_type' => 'post',
    'has_archive' => false, 
    'hierarchical' => true,
    'menu_position' => null,
    'supports' => array( 'title', 'editor' )
  ); 

  register_post_type('authors',$args);

  $labels = array(
    'name' => 'Books'
  );

  $args = array(
    'labels' => $labels,
    'public' => true,
    'publicly_queryable' => true,
    'show_ui' => true, 
    'show_in_menu' => true, 
    'query_var' => true,
    'rewrite' => array(
        'slug' => 'author/%authors%',
        'with_front' => FALSE,
    ),
    'with_front' => false,
    'capability_type' => 'post',
    'has_archive' => false, 
    'hierarchical' => true,
    'menu_position' => null,
    'supports' => array( 'title', 'editor' )
  ); 

  register_post_type('books',$args);


  $labels = array(
    'name' => 'Chapters'
   );

  $args = array(
    'labels' => $labels,
    'public' => true,
    'publicly_queryable' => true,
    'show_ui' => true, 
    'show_in_menu' => true, 
    'query_var' => true,
    'rewrite' => array(
        'slug' => 'author/%authors%/%books%',
        'with_front' => FALSE,
    ),
    'with_front' => FALSE,
    'capability_type' => 'post',
    'has_archive' => false, 
    'hierarchical' => true,
    'menu_position' => null,
    'supports' => array( 'title', 'editor' )
  ); 

  register_post_type('chapters',$args);

}

add_action( 'init', 'cpt_init' );

それで、著者、本、章が最初にすべて一致するように、書き換えルールの優先度を変更する方法はありますか?

post_type_linkフィルターを追加する必要があることもわかっていますが、これは最初にパーマリンクを正しく設定することに次ぐものです。そのフィルターがどのように機能するかについての包括的な概要がどこにあるかを誰かが知っているなら、それはありがたいです。


ページの使用だけを検討しましたか?正しいパーマリンク構造が自動的に得られます。
マイケルハンプトン

私は間違いなくそれを考えました。ページの問題は、1人の作成者に対して100の孫アイテムがある可能性があることです。これは、ページ管理者での管理が非常に困難になります。また、投稿タイプでクエリできる必要があります。
ダルトン

私はソリューションに取り組んでいますが、簡単な質問があります。各パーマリンクの前に「作成者」を置くことが重要ですか?それはステッカーのようですから。特にWPの作成者ページにも使用されているパーマリンクスラグなので、WordPressを少し混乱させていると思います。「作者」が必要な場合、私はすべてがまだできると思います...それはもっと複雑になるだけです。
レイチェルカーデン2012

おっと、作者が組み込みのWP作者のスラッグと競合することを知りませんでした。いいえ、それは必須ではありません。何でもかまいません。CPTなので何かが必要思っていましたが、「ライター」や他の何かでも簡単にできます。
ダルトン

混乱は、実際にはCPTがベーススラグとして「著者」を共有していることにあることに気づきました。CPTの「著者」のスラッグとして「著者」を設定し、CPTの「書籍」に「author /%author%」を設定し、CPTの「章」に「author /%author%/%book%」を設定すると、 」の場合、WordPressは「本」の投稿と「章」の投稿を文字通り「著者」の階層的な子投稿と見なします。それは理にかなっていますか?私のテストでは、「著者」をCPTの「著者」のベースとして維持することができ、問題なく機能します。だから私の前の質問を次のように置き換えてください:「著者」が必要ですか、それともスラッグは%author%で始めることができますか?
レイチェルカーデン2012

回答:


11

あなたはパーマリンクのベーススラグ、すなわちとして「作者」を維持したい場合はexample.com/authors/stephen-king/、「著者のCPT用example.com/authors/stephen-king/the-shining/のために「本」CPTおよびexample.com/authors/stephen-king/the-shining/chapter-3/「チャプター」CPTの場合、WordPressはほとんどすべてが「著者」投稿または「著者」の階層的な子であると考えます'投稿、そしてそうではないので、WordPressは最終的に非常に混乱します。

そうは言っても、非常に基本的な回避策はありますが、パーマリンク構造が常に同じ順序である限り、つまり、「authors」という単語の後には必ず著者のスラッグが続き、その後には常に本のスラッグが続きます。章のナメクジによって、あなたは行ってもいいはずです。

このソリューションでは、「chapters」と「books」のカスタム投稿タイプ定義でリライトスラグを定義する必要はありませんが、「authors」リライトスラグを単に「authors」として設定し、次のコードをfunctions.phpに配置します書き換えルールをファイルして「フラッシュ」します。

add_action( 'init', 'my_website_add_rewrite_tag' );
function my_website_add_rewrite_tag() {
    // defines the rewrite structure for 'chapters', needs to go first because the structure is longer
    // says that if the URL matches this rule, then it should display the 'chapters' post whose post name matches the last slug set
    add_rewrite_rule( '^authors/([^/]*)/([^/]*)/([^/]*)/?','index.php?chapters=$matches[3]','top' );
    // defines the rewrite structure for 'books'
    // says that if the URL matches this rule, then it should display the 'books' post whose post name matches the last slug set
    add_rewrite_rule( '^authors/([^/]*)/([^/]*)/?','index.php?books=$matches[2]','top' );   
}

// this filter runs whenever WordPress requests a post permalink, i.e. get_permalink(), etc.
// we will return our custom permalink for 'books' and 'chapters'. 'authors' is already good to go since we defined its rewrite slug in the CPT definition.
add_filter( 'post_type_link', 'my_website_filter_post_type_link', 1, 4 );
function my_website_filter_post_type_link( $post_link, $post, $leavename, $sample ) {
    switch( $post->post_type ) {

        case 'books':

            // I spoke with Dalton and he is using the CPT-onomies plugin to relate his custom post types so for this example, we are retrieving CPT-onomy information. this code can obviously be tweaked with whatever it takes to retrieve the desired information.
            // we need to find the author the book belongs to. using array_shift() makes sure only one author is allowed
            if ( $author = array_shift( wp_get_object_terms( $post->ID, 'authors' ) ) ) {
                if ( isset( $author->slug ) ) {
                    // create the new permalink
                    $post_link = home_url( user_trailingslashit( 'authors/' . $author->slug . '/' . $post->post_name ) );
                }
            }

            break;

        case 'chapters':

            // I spoke with Dalton and he is using the CPT-onomies plugin to relate his custom post types so for this example, we are retrieving CPT-onomy information. this code can obviously be tweaked with whatever it takes to retrieve the desired information.
            // we need to find the book it belongs to. using array_shift() makes sure only one book is allowed
            if ( $book = array_shift( wp_get_object_terms( $post->ID, 'books' ) ) ) {

                // now to find the author the book belongs to. using array_shift() makes sure only one author is allowed
                $author = array_shift( wp_get_object_terms( $book->term_id, 'authors' ) );

                if ( isset( $book->slug ) && $author && isset( $author->slug ) ) {
                    // create the new permalink
                    $post_link = home_url( user_trailingslashit( 'authors/' . $author->slug . '/' . $book->slug . '/' . $post->post_name ) );
                }

            }

            break;

    }
    return $post_link;
}

CPT-onomiesプラグインの詳細


これは完全に機能します。ありがとうございます。たくさん勉強したような気がします。CPT-onomiesプラグインも非常に優れています。wordpress.org/extend/plugins/cpt-onomies
ダルトン

「ライブラリ」が大きくなると、いくつかの障害に遭遇するかもしれませんが、すでにいくつかのコードを念頭に置いているので、その場合はお知らせください。
レイチェルカーデン2012

@RachelCarden 2冊の本のタイトルが同じで著者が異なる場合はどうしますか?書き換えられたURLに衝突があります!これをどのように解決しますか?
とSegfault

1
@Segfault作成者スラッグをすべて取得して、書き換えルールにハードコーディングできるようにする必要があります。foreach($ author_slugs as $ author_slug){add_rewrite_rule( '^ authors /'。$ author_slug。 '/([[ ^ /] *)/([^ /] *)/? '、' index.php?authors = '。$ author_slug。'&chapters = $ matches [2] '、' top '); add_rewrite_rule( '^ authors /'。$ author_slug。 '/([^/]*)/?','index.php?authors='。$ author_slug。 '&books = $ matches [1]'、 'top') ; }
レイチェルカーデン2013年

あなたが使用することができます@Segfault )(get_termsをあなたはCPT-onomy、または使用している場合、()get_postsをポスト名/ナメクジを取得します。
レイチェルカーデン2013年

4

私はそのようなシナリオについての個人的な経験はありませんが、ランディ・ホイトは先週WordCamp San Franで、あなたが話しているように聞こえる「下位の投稿タイプ」についてプレゼンテーションを行いました。

これは、彼のプレゼンテーションスライドと、下位の投稿タイプを操作するために彼が作成したプラグインへのリンクを含む、トークの彼のページです。http//randyhoyt.com/wordpress/subordinate-post-types/


おかげで、これは良いリソースのように見えます。これが孫の関係をサポートするかどうかは明らかではありませんが(私のテストではそうではありません)、実際にはパーマリンクには役立ちません。私はすでに子供と親の関係を設定する方法を考え出しました(ただし、これはかなり良い方法ですが)。
ダルトン

1

ルールは、追加のパーマストラクチャーが追加される順序でWP_Rewriteのextra_rules_topに追加されます。したがって、投稿タイプを登録する順序を切り替えると、生成される書き換えルールの順序が切り替わり、チャプターの書き換えが最初に一致します。ただし、他のpost_typesのquery_varを使用しているため、wp_queryは、目的の章と一致する前に、それらのいずれかをクエリされた投稿名として一致する可能性があります。

親の作者と親の本のプレースホルダーを表す新しい書き換えタグを作成します。

add_rewrite_tag('%parent-book%', '([^/]+)', 'parent_book=');

これを行うときは、「query_vars」をフィルタリングして「parent_book」を公開する必要があります。次に、pre_get_postsにフィルターを追加して、parent_book query_varとして設定された名前をpost_idに変換し、「post_parent」として設定する必要があります。


あなたが言及したフィルターのコード例を教えていただけませんか?また、孫CPTの書き換えタグはどのようになりますか?
ダルトン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.