ประเภทโพสต์ที่กำหนดเองที่ซ้อนกันพร้อม Permalinks


9

ฉันกำลังพยายามตั้งค่าโครงสร้างประเภทโพสต์ที่กำหนดเองหลายระดับด้วยลิงก์ถาวรที่มีหน้าตาเช่นเดียวauthors/books/chaptersกับผู้แต่งหนังสือและบททั้งหมดตั้งค่าเป็นประเภทโพสต์ที่กำหนดเองของพวกเขาเอง ตัวอย่างเช่น URL ทั่วไปในไซต์นี้อาจดูเหมือนexample.com/authors/stephen-king/the-shining/chapter-3/

แต่ละบทสามารถเป็นของหนังสือเล่มเดียวเท่านั้นและแต่ละเล่มสามารถเป็นของผู้เขียนคนเดียวเท่านั้น ฉันได้พิจารณาใช้ taxonomies แทน CPT สำหรับผู้แต่งและหนังสือ แต่ฉันต้องเชื่อมโยงข้อมูลเมตากับแต่ละรายการและฉันชอบอินเทอร์เฟซสำหรับโพสต์นี้

ฉันเป็นวิธีที่นั่นโดยเพียงตั้งค่าโพสต์ที่กำหนดเองแต่ละรายการให้เป็นรายการย่อยใน CPT หนึ่งระดับ ตัวอย่างเช่นฉันสร้าง "บทที่ 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ตัวกรอง แต่ดูเหมือนว่ารองสำหรับการได้รับความคิดเห็นในตอนแรก หากใครรู้ว่าฉันสามารถหาภาพรวมที่ครอบคลุมเกี่ยวกับวิธีการทำงานของตัวกรองนั้นจะได้รับการชื่นชม


คุณคิดว่าจะใช้เพจหรือไม่? คุณจะได้รับโครงสร้างลิงก์ที่ถูกต้องโดยอัตโนมัติ
Michael Hampton

ฉันคิดว่ามันแน่นอน ปัญหาเกี่ยวกับหน้าเว็บคือเราอาจมีลูกหลาน 100 รายการสำหรับผู้เขียนคนเดียวซึ่งจะยากในการจัดการในหน้าผู้ดูแลระบบ นอกจากนี้เราต้องสามารถค้นหาตามประเภทโพสต์ได้
Dalton

ฉันกำลังหาทางแก้ปัญหา แต่ฉันมีคำถามสั้น ๆ : มันสำคัญหรือไม่ที่จะมี 'ผู้แต่ง' ต่อหน้าลิงก์ถาวรแต่ละอัน? เพราะดูเหมือนว่าจะเป็นคนขี้เหนียว ฉันคิดว่ามันสับสน WordPress มากเกินไปโดยเฉพาะอย่างยิ่งเนื่องจากกระสุนบุ้งลิงก์ยังใช้สำหรับหน้าผู้เขียน WP หากจำเป็นต้องมี 'ผู้แต่ง' ฉันคิดว่าสิ่งทั้งหมดยังไม่สามารถทำได้ ... มันจะซับซ้อนมากขึ้น
Rachel Carden

โอ๊ะฉันไม่ทราบว่าผู้เขียนจะขัดแย้งกับกระสุนของผู้เขียน WP ในตัว ไม่นั่นไม่จำเป็นมันอาจเป็นอะไรก็ได้ ฉันคิดว่าฉันต้องการบางสิ่งที่นั่นเพราะมันเป็น CPT แต่มันอาจจะเป็น "นักเขียน" หรืออะไรก็ได้
Dalton

ฉันรู้ว่าความสับสนอยู่ที่การแชร์ 'ผู้เขียน' ของ CPT ในฐานะฐานกระสุน เมื่อคุณตั้งค่า 'ผู้แต่ง' เป็นบุ้งสำหรับ CPT 'ผู้แต่ง' และจากนั้นคุณตั้ง 'ผู้เขียน /% ผู้เขียน%' สำหรับ 'หนังสือ' และ 'ผู้เขียน /% ผู้เขียน% /% หนังสือ%' สำหรับบท 'CPT' 'จากนั้น WordPress คิดว่าโพสต์สำหรับ' หนังสือ 'และโพสต์สำหรับ' บท 'นั้นเป็นแบบเรียงลำดับชั้นของเด็ก ๆ สำหรับ' ผู้เขียน ' มันสมเหตุสมผลไหม ในการทดสอบของฉันคุณสามารถให้ 'ผู้เขียน' เป็นพื้นฐานสำหรับ 'ผู้เขียน CPT' และมันก็ใช้ได้ดี ดังนั้นแทนที่คำถามก่อนหน้าของฉันด้วย: คุณต้องการ 'ผู้เขียน' หรือกระสุนเริ่มต้นด้วย% ผู้เขียน% ได้ไหม?
Rachel Carden

คำตอบ:


11

หากคุณต้องการให้ 'ผู้แต่ง' เป็นบุ้งพื้นฐานในลิงก์ถาวรเช่นexample.com/authors/stephen-king/สำหรับ CPT 'ผู้เขียน' ให้ตัวอย่างเช่น. com/ authors/stephen- king/ the- shining/สำหรับ CPT 'books' และexample.com/authors/stephen-king/the-shining/chapter-3/สำหรับ 'บท' CPT, WordPress จะคิดว่าทุกอย่างสวยมากทุกอย่างเป็นโพสต์ 'ผู้แต่ง' หรือเด็กลำดับชั้นของผู้เขียน ' โพสต์และเนื่องจากไม่ใช่กรณีนั้นในที่สุด WordPress ก็สับสนมาก

ด้วยที่กล่าวว่ามีวิธีการแก้ปัญหาที่ค่อนข้างพื้นฐาน แต่ตราบใดที่โครงสร้างความคิดเห็นของคุณเป็นไปตามคำสั่งเดียวกันเสมอนั่นคือคำว่า 'ผู้แต่ง' จะตามมาด้วยตัวบุ้งผู้เขียนซึ่งตามมาด้วยตัวบุบุหนังสือที่ตามมาเสมอ โดยทากบทที่แล้วคุณควรจะดีไป

ในโซลูชันนี้ไม่จำเป็นต้องกำหนดกระสุนเขียนใหม่ในคำจำกัดความประเภทโพสต์ที่กำหนดเองสำหรับ 'บท' และ 'หนังสือ' แต่ตั้งค่า 'เขียน' เขียนทับกระสุนเป็นเพียง 'ผู้เขียน' วางรหัสต่อไปนี้ใน function.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
Dalton

ฉันรู้สึกว่าคุณอาจเจออุปสรรคบางอย่างในขณะที่ "ห้องสมุด" ของคุณเติบโตขึ้น แต่ฉันมีรหัสอยู่ในใจอยู่แล้วดังนั้นหากคุณแจ้งให้เราทราบ
Rachel Carden

@RachelCarden คุณจะทำอย่างไรเมื่อหนังสือสองเล่มมีชื่อเหมือนกัน แต่เป็นผู้แต่งต่างกัน? จะมีการปะทะกันใน URL ที่เขียนใหม่! คุณจะแก้ปัญหานี้อย่างไร
Segfault

1
@Segfault คุณจะต้องดึงทากผู้เขียนทั้งหมดเพื่อให้คุณสามารถเขียนโค้ดลงในกฎการเขียนใหม่: foreach ($ author_slugs เป็น $ author_slug) {add_rewrite_rule ('^ ผู้เขียน /' $ author_slug. '/ ([^] ^ /] *) / ([^ /] *) /? ',' index.php? ผู้เขียน = '. $ author_slug.' & บท = $ ตรงกับ [2] ',' top '); add_rewrite_rule ('^ ผู้เขียน /'. $ author_slug. '/( [^ วรรค] / -----------)/?','index.php?authors='. $ author_slug. '& หนังสือ = $ ตรงกับ [1]', 'top') ; }
Rachel Carden

@Segfault คุณสามารถใช้get_terms ()ถ้าคุณใช้ CPT-onomy หรือ get_posts ()เพื่อดึงชื่อโพสต์ / กระสุน
Rachel Carden

4

ฉันไม่ได้มีประสบการณ์ส่วนตัวกับสถานการณ์ดังกล่าว แต่แรนดี้ฮอยต์ทำการนำเสนอที่ WordCamp San Fran เมื่อสัปดาห์ที่แล้วเกี่ยวกับ "ประเภทโพสต์รอง" ที่ดูเหมือนว่าคุณกำลังพูดถึง

นี่คือหน้าของเขาสำหรับการพูดคุยที่มีสไลด์การนำเสนอและลิงก์ไปยังปลั๊กอินที่เขาสร้างขึ้นสำหรับการทำงานกับประเภทโพสต์รอง: http://randyhoyt.com/wordpress/subordinate-post-types/


ขอบคุณดูเหมือนว่าเป็นทรัพยากรที่ดี ไม่ชัดเจนว่าสิ่งนี้สนับสนุนความสัมพันธ์ของลูกหลานหรือไม่ (ดูเหมือนจะไม่ได้ทดสอบในตัวฉัน) และมันก็ไม่ได้ช่วยในการเพิ่มความคิดเห็น ฉันได้คิดหาวิธีตั้งค่าความสัมพันธ์ลูก / ผู้ปกครองของฉัน (แม้ว่านี่จะเป็นวิธีที่ดีมากที่จะทำ) แต่ Permalinks เป็นปัญหาที่ฉันติดอยู่ในตอนนี้
Dalton

1

กฎจะได้รับการเพิ่มเข้าไปใน extra_rules_top ของ WP_Rewrite ตามลำดับที่จะเพิ่ม permastructs พิเศษ ดังนั้นการเปลี่ยนลำดับที่คุณลงทะเบียนประเภทโพสต์จะเปลี่ยนลำดับของกฎการเขียนซ้ำที่สร้างขึ้นทำให้บทที่เขียนได้ตรงกันก่อน อย่างไรก็ตามเนื่องจากคุณใช้ query_var จากอีก post_types wp_query อาจสิ้นสุดการจับคู่หนึ่งในนั้นเป็นชื่อโพสต์สอบถามก่อนที่จะจับคู่บทที่คุณต้องการ

ฉันจะสร้างแท็ก rewrite ใหม่เพื่อเป็นตัวแทนตัวยึดสำหรับผู้แต่งผู้ปกครองและผู้ปกครองหนังสือเช่น:

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

เมื่อทำสิ่งนี้คุณจะต้องกรอง 'query_vars' เพื่อให้ 'parent_book' เป็นแบบสาธารณะ จากนั้นคุณจะต้องเพิ่มตัวกรองเพื่อ pre_get_posts ที่จะแปลงชื่อชุดเป็น parent_book query_var เป็น post_id และตั้งเป็น 'post_parent'


คุณช่วยยกตัวอย่างรหัสสำหรับตัวกรองที่คุณพูดถึงได้ไหม นอกจากนี้แท็กที่เขียนใหม่จะมีลักษณะอย่างไรสำหรับหลาน CPT
Dalton
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.