web-dev-qa-db-ja.com

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

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

各章は1冊の本にのみ属することができ、各本は1人の著者にのみ属することができます。著者や書籍にはCPTではなく分類法を使用することを検討しましたが、各項目にメタデータを関連付ける必要があります。そのためにはポストインターフェイスを使用することをお勧めします。

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

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

Here's a screenshot of my rewrite analyzer.

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フィルタを追加しなければならないこともわかっていますが、それはパーマリンクを最初から正しくすることに次ぐものと思われます。そのフィルタがどのように機能するかの包括的な概要をどこで見つけることができるかを誰かが知っていれば、それは高く評価されるでしょう。

9
Dalton

パーマリンクの基本スラグとして 'authors'を保持したい場合、つまり 'authors' CPTの場合はexample.com/authors/stephen-king/example.com/authors/stephen) 'books' CPTの場合は-king/the-shining /、 '章'のCPTの場合はexample.com/authors/stephen-king/the-shining/chapter-3/のように、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プラグインについてさらに詳しく

11
Rachel Carden

私はそのようなシナリオに関する個人的な経験はありませんが、先週末に行われた "Subordinate Post Types"について、Randy HoytがWordCamp San Franでプレゼンテーションをしました。

これが講演のスライドと彼が従属する投稿タイプを扱うために作ったプラグインへのリンクを含む彼のページです: http://randyhoyt.com/wordpress/subordinate-post-types/

4
mannieschumpert

ルールは、追加のpertructが追加された順にWP_Rewriteのextra_rules_topに追加されます。そのため、投稿タイプを登録する順序を切り替えると、書き換えルールが生成される順序が切り替わり、章の書き換えが最初に一致するようになります。ただし、他のpost_typeのquery_varを使用しているため、wp_queryは、希望する章に一致する前に、クエリされた投稿名としてこれらのいずれかに一致する可能性があります。

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

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

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

1
prettyboymp