Cara mengatur hubungan orang tua-anak di antara jenis posting khusus yang berbeda

14

Saya baru saja mengatur hubungan post / parent antara tipe posting "episode" dan tipe posting "kartun-seri."

Saya menggunakan sedikit kode ini untuk ditambahkan di kotak meta untuk menetapkan induk dari jenis posting lain:

add_action('admin_menu', function() {
    remove_meta_box('pageparentdiv', 'episodes', 'normal');
});
add_action('add_meta_boxes', function() {
    add_meta_box('episodes-parent', 'Cartoon Series', 'episodes_attributes_meta_box', 'episodes', 'side', 'default');
});

function episodes_attributes_meta_box($post) {
    $post_type_object = get_post_type_object($post->post_type);
    if ( $post_type_object->hierarchical ) {
        $pages = wp_dropdown_pages(array('post_type' => 'cartoon-series', 'selected' => $post->post_parent, 'name' => 'parent_id', 'show_option_none' => __('(no parent)'), 'sort_column'=> 'menu_order, post_title', 'echo' => 0));
        if ( ! empty($pages) ) {
            echo $pages;
        } // end empty pages check
    } // end hierarchical check.
}

Itu berfungsi pada layar admin dalam memungkinkan saya untuk mengatur seri sebagai orangtua untuk episode, tetapi ketika saya mencoba untuk melihat posting, saya mendapatkan 404. Struktur url adalah:

domain/episodes/series-name/episode-name

Url untuk seri ini adalah:

domain/cartoon-series/series-name

Saya ingin url untuk episode ini:

domain/cartoon-series/series-name/episode-name

Apa yang saya lewatkan? Apakah mungkin untuk membuat seluruh jenis posting anak dari jenis posting lain? Jadi, saya bahkan bisa mendapatkan url untuk daftar episode:

domain/cartoon-series/series-name/episodes

Terima kasih! Mat


Seperti yang diminta, berikut adalah kode untuk dua jenis pos kustom yang dimaksud:

$labels = array(
    "name" => "Cartoon Series",
    "singular_name" => "Cartoon Series",
    "menu_name" => "Cartoon Series",
    "all_items" => "All Cartoon Series",
    "add_new" => "Add New",
    "add_new_item" => "Add New Cartoon Series",
    "edit" => "Edit",
    "edit_item" => "Edit Cartoon Series",
    "new_item" => "New Cartoon Series",
    "view" => "View",
    "view_item" => "View Cartoon Series",
    "search_items" => "Search Cartoon Series",
    "not_found" => "No Cartoon Series Found",
    "not_found_in_trash" => "No Cartoon Series Found in Trash",
    "parent" => "Parent Cartoon Series",
    );

$args = array(
    "labels" => $labels,
    "description" => "",
    "public" => true,
    "show_ui" => true,
    "has_archive" => true,
    "show_in_menu" => true,
    "exclude_from_search" => false,
    "capability_type" => "post",
    "map_meta_cap" => true,
    "hierarchical" => true,
    "rewrite" => array( "slug" => "cartoon-series", "with_front" => true ),
    "query_var" => true,
    "supports" => array( "title", "revisions", "thumbnail" ),           );
register_post_type( "cartoon-series", $args );

$labels = array(
    "name" => "Episodes",
    "singular_name" => "Episode",
    );

$args = array(
    "labels" => $labels,
    "description" => "",
    "public" => true,
    "show_ui" => true,
    "has_archive" => true,
    "show_in_menu" => true,
    "exclude_from_search" => false,
    "capability_type" => "post",
    "map_meta_cap" => true,
    "hierarchical" => true,
    "rewrite" => array( "slug" => "episodes", "with_front" => true ),
    "query_var" => true,
    "supports" => array( "title", "revisions", "thumbnail" ),           );
register_post_type( "episodes", $args );

Saya menggunakan plugin CPT UI, jadi saya tidak dapat mengedit kode itu secara langsung. Itu hanya kode ekspor yang disediakan CPT UI.

Saya tidak punya kode lain yang menghubungkan kedua CPT. Mungkin itu yang saya lewatkan. Saya baru saja menemukan kode online yang menempatkan metabox pada halaman untuk melakukan penautan. Apakah itu tidak cukup untuk melakukan pekerjaan itu? Sepertinya itu mengatur post_parent.

Terima kasih! Mat

Mattaton
sumber
Maaf, tapi saya salah. Hubungan orangtua-anak diatur dengan benar. Kotak meta tidak menggunakan bidang meta (itulah yang membingungkan saya saat pertama kali), ia menggunakan parent_idkueri var dan tidak perlu lagi kode untuk mengatur hubungan. Masalahnya adalah bahwa URL yang dihasilkan tidak dikenali oleh WordPress. Saya sudah berusaha menemukan aturan penulisan ulang yang membuatnya berfungsi tetapi saya belum berhasil. Saya sekarang sedang menyelidiki suatu solusi.
cybmeta
Setelah beberapa penyelidikan, saya pikir Anda tidak bisa berfungsi seperti yang Anda inginkan. Memiliki jenis posting sebagai induk dari jenis posting lain tampaknya tidak mungkin. Yah, itu mungkin, dengan kode Anda bahwa hubungan itu sebenarnya sudah diatur, tetapi melihat post anak tidak berfungsi di frontend. Saya sudah mencoba menulis ulang aturan dan mengaitkannya pre_get_postsuntuk mengubah kueri tanpa hasil, sesuatu yang lebih rumit terlibat yang belum dapat saya pahami. Seperti memiliki kucing menjadi orangtua anjing. Saya menyarankan untuk menggunakan hanya satu jenis posting hirarkis atau mengatur hubungan dengan menggunakan bidang meta .
cybmeta
Saya pikir satu jenis tulisan hirarki cocok dengan situasi Anda.
cybmeta
2
Saya benar-benar berusaha TIDAK menjadi rumit dengan ini. Jika solusi yang lebih elegan tersedia, saya dengar. Saya baru mengenal WP secara umum dan sejauh ini telah melakukannya dengan baik, tetapi yang ini telah membuat saya bingung. Biasanya, saya hanya akan membuat seri kartun kategori dan menugaskannya untuk episode. Masalahnya adalah, saya juga punya data bersarang lain selain episode untuk dimasukkan dalam serial kartun. Jadi, sepertinya serial kartun harus menjadi CPT juga. Ini rumit! :-D Bisakah Anda menjelaskan kepada saya apa yang Anda maksud dengan menggunakan hanya satu jenis posting hirarkis?
Mattaton

Jawaban:

9

Akhirnya saya menemukan solusi yang berfungsi. Serial kartun dapat didaftarkan seperti yang Anda lakukan tetapi episode jenis posting kustom tidak bisa hirarkis (saya pikir WordPress mengharapkan konten induk menjadi jenis yang sama dengan konten anak jika hubungan diatur menggunakan post_parentdalam wp_poststabel database).

Saat mendaftarkan episode, aturan penulisan ulang harus diatur ke siput yang Anda inginkan, yaitu cartoon-series/%series_name%. Kemudian kita bisa memfilter tautan episode untuk menggantikan %series_name%dengan nama sebenarnya dari cartoon-seriesjenis posting induk dan aturan penulisan ulang untuk mengatakan ke WordPress ketika jenis posting seri kartun diminta dan kapan episode.

add_action('init', function(){
    $labels = array(
        "name" => "Cartoon Series",
        "singular_name" => "Cartoon Series",
        "menu_name" => "Cartoon Series",
        "all_items" => "All Cartoon Series",
        "add_new" => "Add New",
        "add_new_item" => "Add New Cartoon Series",
        "edit" => "Edit",
        "edit_item" => "Edit Cartoon Series",
        "new_item" => "New Cartoon Series",
        "view" => "View",
        "view_item" => "View Cartoon Series",
        "search_items" => "Search Cartoon Series",
        "not_found" => "No Cartoon Series Found",
        "not_found_in_trash" => "No Cartoon Series Found in Trash",
        "parent" => "Parent Cartoon Series",
    );

    $args = array(
        "labels" => $labels,
         "description" => "",
        "public" => true,
        "show_ui" => true,
        "has_archive" => true,
        "show_in_menu" => true,
        "exclude_from_search" => false,
        "capability_type" => "post",
        "map_meta_cap" => true,
        "hierarchical" => true,
        "rewrite" => array( "slug" => "cartoon-series", "with_front" => true ),
        "query_var" => true,
        "supports" => array( "title", "revisions", "thumbnail" )
    );

    register_post_type( "cartoon-series", $args );

    $labels = array(
        "name" => "Episodes",
        "singular_name" => "Episode",
    );

    $args = array(
        "labels" => $labels,
        "description" => "",
        "public" => true,
        "show_ui" => true,
        "has_archive" => true,
        "show_in_menu" => true,
        "exclude_from_search" => false,
        "capability_type" => "post",
        "map_meta_cap" => true,
        "hierarchical" => false,
        "rewrite" => array( "slug" => "cartoon-series/%series_name%", "with_front" => true ),
        "query_var" => true,
        "supports" => array( "title", "revisions", "thumbnail" )
    );

    register_post_type( "episodes", $args );

});

add_action('add_meta_boxes', function() {
    add_meta_box('episodes-parent', 'Cartoon Series', 'episodes_attributes_meta_box', 'episodes', 'side', 'default');
});

function episodes_attributes_meta_box($post) {
        $pages = wp_dropdown_pages(array('post_type' => 'cartoon-series', 'selected' => $post->post_parent, 'name' => 'parent_id', 'show_option_none' => __('(no parent)'), 'sort_column'=> 'menu_order, post_title', 'echo' => 0));
        if ( ! empty($pages) ) {
            echo $pages;
        } // end empty pages check
}

add_action( 'init', function() {

    add_rewrite_rule( '^cartoon-series/(.*)/([^/]+)/?$','index.php?episodes=$matches[2]','top' );

});

add_filter( 'post_type_link', function( $link, $post ) {
    if ( 'episodes' == get_post_type( $post ) ) {
        //Lets go to get the parent cartoon-series name
        if( $post->post_parent ) {
            $parent = get_post( $post->post_parent );
            if( !empty($parent->post_name) ) {
                return str_replace( '%series_name%', $parent->post_name, $link );
            }
        } else {
            //This seems to not work. It is intented to build pretty permalinks
            //when episodes has not parent, but it seems that it would need
            //additional rewrite rules
            //return str_replace( '/%series_name%', '', $link );
        }

    }
    return $link;
}, 10, 2 );

CATATAN : Ingatlah untuk menyiram aturan penulisan ulang setelah menyimpan kode di atas dan sebelum mencobanya. Pergi ke wp-admin/options-permalink.phpdan klik simpan untuk mengatur ulang aturan penulisan ulang.

CATATAN 2 : Mungkin ada lebih banyak aturan penulisan ulang yang harus ditambahkan, misalnya untuk berfungsi untuk posting paginate. Juga mungkin perlu beberapa pekerjaan lagi untuk memiliki solusi yang lengkap, misalnya, ketika menghapus cartoon-serieshapus juga semua episode anak? Tambahkan filter di layar edit admin untuk memfilter episode dengan pos induk? Ubah judul episode di layar edit admin untuk menampilkan nama seri induk?

cybmeta
sumber
Terima kasih telah melihat ini! Tampaknya kode yang Anda poskan menjatuhkan nama serial kartun dari url. Alih-alih mengganti% series_name% dengan nama episode,% series_name% harus menjadi nama induk dari episode tersebut. Nama episode akan setelah itu. Untuk beberapa alasan, kotak Seri Kartun tidak diisi untuk saya untuk memilih orangtua. Itu sebabnya saya pikir episode perlu hierarkis. Mencoba mencari tahu alasannya.
Mattaton
Ya, episode harus hierarkis agar kotak meta Seri Kartun dapat diisi.
Mattaton
Dengan episode-episode yang hierarkis sehingga saya dapat mengatur induknya, urlnya menjadi lebih buruk. Dengan siput seperti yang Anda sarankan, saya mendapatkan nama seri di url dua kali. Jadi, alih-alih domain/episodes/series-name/episode-nameseperti sebelumnya, saya dapatdomain/episodes/series-name/series-name/episode-name
Mattaton
Seperti yang saya katakan, episode tidak bisa hirarkis. Saya memodifikasi kode kotak meta untuk diisi dengan jenis posting non-hierarkis. Gunakan kode persis yang saya posting, saya mengujinya dan berfungsi. Jika Anda menggunakan kode lain saya tidak bisa tahu apa yang salah. Cukup salin dan tempel kode dari jawaban dan ujilah. Anda mungkin perlu menonaktifkan plugin CPT UI atau, setidaknya, menghapus jenis posting khusus dari plugin karena terdaftar dalam kode.
cybmeta
Ah, permintaan maaf saya, saya dengan cepat memindai dan berpikir bagian itu sama. Anda benar, halaman memuat sekarang dan url terlihat benar.
Mattaton
-1

Anda perlu menulis kode parsing URL Anda sendiri untuk itu sebagai wordpress perlu mengetahui jenis posting yang mencoba untuk mengambil dari DB berdasarkan struktur url dan struktur url Anda tidak memberikan petunjuk apa pun untuk ini.

Ini bukan sesuatu yang sangat mudah dilakukan dengan aturan penulisan ulang API wordpress, tetapi tidak ada yang mencegah Anda melewati mekanisme penulisan ulang dan mem-parsing url sendiri. Sesuatu seperti 1. menjalankan aturan rewite wordpress. Jika suatu konten ditemukan, tampilkan dan keluar 2. dapatkan bagian pertama dari url, periksa apakah ada posting yang cocok dengan siput dengan tipe posting yang diharapkan 3. loop pada bagian-bagian lain dari URL memverifikasi bahwa posting ada dan dalam tipe yang tepat. 4. jika semuanya cocok menampilkan posting terakhir yang ditemukan, yang lain menampilkan halaman 404

Mark Kaplun
sumber