Jenis posting khusus bersarang dengan tautan permanen

9

Saya mencoba menyiapkan struktur jenis pos kustom multi-level dengan permalink yang terlihat seperti authors/books/chapters, dengan penulis, buku, dan bab semua diatur sebagai jenis pos kustom mereka sendiri. Misalnya, URL tipikal pada situs ini mungkin terlihatexample.com/authors/stephen-king/the-shining/chapter-3/

Setiap bab hanya dapat dimiliki oleh satu buku, dan setiap buku hanya dapat dimiliki oleh satu penulis. Saya telah mempertimbangkan menggunakan taksonomi alih-alih CPT untuk penulis dan buku, tetapi saya harus mengaitkan metadata dengan setiap item dan saya lebih suka antarmuka posting untuk ini.

Saya sebagian besar jalan di sana dengan hanya mengatur setiap pos kustom sebagai anak dari entri di CPT satu tingkat ke atas. Misalnya, saya membuat "Bab 3" dan menetapkan "The Shining" sebagai induk menggunakan kotak meta khusus. "The Shining" pada gilirannya memiliki "Stephen King" sebagai orang tua. Saya tidak kesulitan membuat hubungan ini.

Saya menggunakan tag menulis ulang di siput CPT dan permalink ingin bekerja, tetapi mereka tidak benar. Dengan menggunakan penganalisis penulisan ulang, saya dapat melihat bahwa aturan penulisan ulang sebenarnya dibuat, tetapi aturan tersebut tampaknya tidak berada dalam urutan yang benar sehingga aturan lain diproses terlebih dahulu.

Berikut adalah screenshot penganalisa penulisan ulang saya.

Inilah cara saya mendaftarkan CPT saya:

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' );

Jadi, adakah cara untuk mengubah prioritas aturan penulisan ulang saya sehingga penulis, buku, dan bab semuanya cocok terlebih dahulu?

Saya juga tahu bahwa saya harus menambahkan post_type_linkfilter, tapi itu tampaknya sekunder untuk mendapatkan permalink yang benar. Jika ada yang tahu di mana saya dapat menemukan ikhtisar komprehensif tentang cara kerja filter itu, itu akan dihargai.

Dalton
sumber
Sudahkah Anda mempertimbangkan untuk menggunakan Halaman? Anda akan mendapatkan struktur permalink yang tepat secara otomatis.
Michael Hampton
Saya sudah mempertimbangkannya. Masalah dengan halaman adalah bahwa kami mungkin memiliki 100 item cucu untuk satu penulis, yang akan sangat sulit dikelola di halaman admin. Juga, kita harus dapat melakukan query berdasarkan tipe posting.
Dalton
Saya sedang mengerjakan solusi tetapi saya punya pertanyaan cepat: apakah kunci untuk memiliki 'penulis' di depan setiap permalink? Karena itu kelihatannya menjadi ngotot. Saya pikir itu membingungkan WordPress sedikit terlalu banyak, terutama karena itu siput permalink juga digunakan untuk halaman penulis WP. Jika memiliki 'penulis' diperlukan, saya pikir semuanya masih bisa dilakukan ... itu hanya akan lebih rumit.
Rachel Carden
Ups, saya tidak menyadari bahwa penulis akan mengalami konflik dengan siput WP bawaan. Tidak, itu tidak wajib, bisa apa saja. Saya berasumsi saya membutuhkan sesuatu di sana karena itu adalah CPT, tetapi bisa dengan mudah menjadi "penulis" atau apa pun.
Dalton
Saya menyadari kebingungan sebenarnya terletak pada 'penulis' CPT yang berbagi sebagai siput pangkalan. Setelah Anda menetapkan 'penulis' sebagai siput untuk 'penulis' CPT, dan kemudian Anda menetapkan 'penulis /% penulis%' untuk 'buku' CPT dan 'penulis /% penulis% /% buku%' untuk bab CPT ' ', lalu WordPress berpikir posting untuk' buku 'dan posting untuk' bab 'secara harfiah adalah hierarki posting anak untuk' penulis '. Apakah itu masuk akal? Dalam pengujian saya, Anda bisa menjadikan 'penulis' sebagai dasar untuk 'penulis' CPT dan berfungsi dengan baik. Jadi, ganti pertanyaan saya sebelumnya dengan: apakah Anda memerlukan 'penulis' atau dapatkah siput memulai dengan% penulis%?
Rachel Carden

Jawaban:

11

Jika Anda ingin menjadikan 'penulis' sebagai slug dasar di permalinks, yaitu example.com/authors/stephen-king/ untuk 'CPT penulis', example.com/authors/stephen-king/the-shining/ untuk 'buku' CPT dan contoh.com/authors/stephen-king/the-shining/chapter-3/ untuk 'bab' CPT, WordPress akan berpikir bahwa semuanya adalah pos 'penulis' atau anak hirarki penulis. 'memposting dan, karena bukan itu masalahnya, WordPress akhirnya menjadi sangat bingung.

Dengan itu, ada solusi yang cukup mendasar tetapi selama struktur permalink Anda selalu mengikuti urutan yang sama, yaitu kata 'penulis' selalu diikuti oleh siput penulis, yang selalu diikuti oleh siput buku yang selalu diikuti dengan bab siput, maka Anda harus baik untuk pergi.

Dalam solusi ini, tidak perlu mendefinisikan slug penulisan ulang dalam definisi tipe posting kustom untuk 'bab' dan 'buku', tetapi atur slug menulis ulang 'penulis' hanya sebagai 'penulis', tempatkan kode berikut di fungsi Anda.php file dan "siram" aturan penulisan ulang Anda.

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;
}

Pelajari lebih lanjut tentang plugin CPT-onomies

Rachel Carden
sumber
Ini bekerja dengan baik, terima kasih! Saya merasa seperti baru saja belajar banyak. Plugin CPT-onomies juga sangat keren. wordpress.org/extend/plugins/cpt-onomies
Dalton
Saya merasa Anda mungkin menemukan beberapa kendala ketika "perpustakaan" Anda tumbuh tetapi saya sudah memiliki beberapa kode dalam pikiran jadi, jika Anda melakukannya, beri tahu saya.
Rachel Carden
@RachelCarden Apa yang Anda lakukan ketika dua buku memiliki judul yang sama tetapi penulis yang berbeda? Akan ada tabrakan di URL yang ditulis ulang! Bagaimana anda menyelesaikan ini?
Segfault
1
@Segfault Anda harus mengambil semua siput penulis sehingga Anda dapat mengkodekannya dengan keras ke aturan penulisan ulang: foreach ($ author_slug sebagai $ author_slug) {add_rewrite_rule ('^ penulis /'. $ Author_slug. '/ ([ ^ /] *) / ([^ /] *) /? ',' index.php? penulis = '. $ author_slug.' & bab = $ cocok [2] ',' top '); add_rewrite_rule ('^ penulis /'. $ author_slug. '/([^/[*)/?','index.php?authors='. $ author_slug. '& books = $ cocok [1]', 'top') ; }
Rachel Carden
@Segfault Anda dapat menggunakan get_terms () , jika Anda menggunakan ontom CPT, atau get_posts () untuk mengambil nama posting / siput.
Rachel Carden
4

Saya tidak punya pengalaman pribadi dengan skenario seperti itu, tetapi Randy Hoyt melakukan presentasi di WordCamp San Fran akhir pekan lalu tentang "Subordinate Post Types" yang terdengar seperti apa yang Anda bicarakan.

Inilah halamannya untuk ceramah yang mencakup slide presentasinya dan tautan ke plugin yang ia buat untuk bekerja dengan jenis posting bawahan: http://randyhoyt.com/wordpress/subordinate-post-types/

mannieschumpert
sumber
Terima kasih, ini sepertinya sumber yang bagus. Tidak jelas apakah ini mendukung hubungan cucu (sepertinya tidak dalam pengujian saya) dan itu sebenarnya tidak membantu permalinks. Saya sudah menemukan cara untuk mengatur hubungan anak / orang tua saya (meskipun ini adalah cara yang cukup baik untuk melakukannya), tetapi permalinks benar-benar masalah yang saya macet sekarang.
Dalton
1

Aturan akan ditambahkan ke extra_rules_top WP_Rewrite dalam urutan bahwa permastruct tambahan ditambahkan. Jadi, mengalihkan urutan yang Anda daftarkan ke jenis tulisan akan mengubah urutan aturan penulisan ulang yang dihasilkan sehingga penulisan ulang bab menjadi cocok terlebih dahulu. Namun, karena Anda menggunakan query_var dari post_types lain, wp_query mungkin akan cocok dengan salah satu dari mereka sebagai nama posting yang di-query sebelum mencocokkan bab seperti yang Anda inginkan.

Saya akan membuat tag penulisan ulang baru untuk mewakili placeholder untuk penulis induk dan buku induk, yaitu:

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

Saat melakukan ini, Anda harus memfilter 'query_vars' untuk membuat 'parent_book' menjadi publik. Maka Anda perlu menambahkan filter ke pre_get_posts yang akan mengubah nama yang ditetapkan sebagai parent_book query_var ke dalam post_id dan menjadikannya sebagai 'post_parent'.

prettyboymp
sumber
Bisakah Anda memberikan contoh kode untuk filter yang Anda sebutkan? Juga, seperti apa bentuk tag penulisan ulang untuk CPT cucu?
Dalton