Cách đặt mối quan hệ cha-con giữa các loại bài đăng tùy chỉnh


14

Tôi vừa thiết lập mối quan hệ bài đăng / phụ huynh giữa loại "tập" và loại bài "phim hoạt hình".

Tôi đã sử dụng bit mã này để thêm vào hộp meta để gán cha mẹ từ một loại bài đăng khác:

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

Điều đó đã làm việc trên màn hình quản trị viên trong việc cho phép tôi đặt sê-ri làm phụ huynh cho tập phim, nhưng khi tôi cố gắng xem bài đăng, tôi nhận được 404. Cấu trúc url là:

domain/episodes/series-name/episode-name

Url cho chuỗi là:

domain/cartoon-series/series-name

Tôi muốn url cho tập phim là:

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

Tôi đang thiếu gì? Có thể làm cho toàn bộ một loại bài đăng con của một loại bài đăng khác? Vì vậy, sau đó tôi thậm chí có thể lấy url cho danh sách các tập là:

domain/cartoon-series/series-name/episodes

Cảm ơn! Matt


Theo yêu cầu, đây là mã cho hai loại bài đăng tùy chỉnh trong câu hỏi:

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

Tôi đang sử dụng plugin UI CPT, vì vậy tôi không thể chỉnh sửa mã đó trực tiếp. Đó chỉ là mã xuất khẩu CPT UI cung cấp.

Tôi không có bất kỳ mã nào khác liên kết hai CPT. Có lẽ đó là những gì tôi đang thiếu. Tôi chỉ tìm thấy mã trực tuyến đặt metabox trên trang để thực hiện liên kết. Nó không đủ để làm công việc? Có vẻ như nó đặt post_parent.

Cảm ơn! Matt


Tôi xin lỗi nhưng tôi đã sai. Mối quan hệ cha-con được đặt chính xác. Hộp meta không sử dụng trường meta (đó là điều khiến tôi bối rối lần đầu tiên), nó sử dụng parent_idvar truy vấn và nó không cần thêm mã để thiết lập mối quan hệ. Vấn đề là URL được tạo không được WordPress nhận ra. Tôi đã cố gắng tìm một quy tắc viết lại để làm cho nó hoạt động nhưng tôi đã không thành công. Bây giờ tôi đang điều tra một giải pháp.
cybmeta

Sau một số điều tra, tôi nghĩ bạn không thể làm cho nó hoạt động như bạn muốn. Có một loại bài đăng là cha mẹ của loại bài đăng khác dường như là không thể. Vâng, có thể, với mã của bạn mối quan hệ đó thực sự được đặt, nhưng nhìn thấy bài đăng con không hoạt động ở mặt trước. Tôi đã thử viết lại các quy tắc và nối vào pre_get_postsđể thay đổi truy vấn nhưng không thành công, đôi khi có liên quan phức tạp hơn mà tôi không thể hiểu được. Giống như có một con mèo là cha mẹ của một con chó. Tôi đề nghị chỉ sử dụng một loại bài đăng phân cấp hoặc đặt thực tế sử dụng các trường meta .
cybmeta 14/03/2015

Tôi nghĩ rằng một loại bài viết hirarchical hoàn toàn phù hợp với tình huống của bạn.
cybmeta 14/03/2015

2
Tôi thực sự đang cố gắng KHÔNG phức tạp với điều này. Nếu một giải pháp thanh lịch hơn có sẵn, tôi là tất cả tai. Tôi mới sử dụng WP nói chung và đã làm khá tốt cho đến nay, nhưng điều này đã làm tôi bối rối. Thông thường, tôi sẽ chỉ làm cho loạt phim hoạt hình trở thành một thể loại và gán nó cho tập phim. Vấn đề là, tôi cũng có các dữ liệu lồng nhau khác ngoài các tập phim đi theo loạt phim hoạt hình. Vì vậy, có vẻ như loạt phim hoạt hình cũng cần phải là một CPT. Nó phức tạp lắm! :-D Bạn có thể giải thích cho tôi ý của bạn khi chỉ sử dụng một loại bài đăng phân cấp không?
Mattaton

Câu trả lời:


9

Cuối cùng tôi đã tìm thấy một giải pháp làm việc. Sê-ri phim hoạt hình có thể được đăng ký như bạn đã làm nhưng các loại bài đăng tùy chỉnh không thể mang tính chất gia truyền (Tôi nghĩ rằng WordPress hy vọng nội dung gốc giống với nội dung con nếu mối quan hệ được đặt post_parenttrong wp_postsbảng cơ sở dữ liệu).

Khi đăng ký tập, quy tắc viết lại phải được đặt thành sên bạn muốn, đó là cartoon-series/%series_name%. Sau đó, chúng ta có thể lọc liên kết các tập để thay thế %series_name%bằng tên thật của cartoon-seriesloại bài đăng gốc và quy tắc viết lại để nói với WordPress khi loại bài đăng loạt phim hoạt hình được yêu cầu và khi nào là tập.

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

LƯU Ý : Hãy nhớ xóa các quy tắc viết lại sau khi lưu mã ở trên và trước để thử nó. Đi đến wp-admin/options-permalink.phpvà nhấp vào lưu để lấy lại quy tắc viết lại.

CHÚ THÍCH 2 : Có lẽ phải thêm nhiều quy tắc viết lại, ví dụ để làm việc cho các bài viết phân trang. Ngoài ra, nó có thể cần thêm một số công việc để có một giải pháp hoàn chỉnh, ví dụ, khi xóa một cartoon-seriesxóa cũng tất cả các tập con? Thêm bộ lọc trong màn hình chỉnh sửa quản trị để lọc các tập theo bài đăng phụ huynh? Sửa đổi tiêu đề tập trong màn hình chỉnh sửa quản trị để hiển thị tên loạt cha mẹ?


Cảm ơn đã xem xét này! Có vẻ như mã bạn đã đăng đang bỏ tên của loạt phim hoạt hình từ url. Thay vì thay thế% series_name% bằng tên của tập phim,% series_name% nên là tên của cha mẹ của tập. Tên tập sẽ là sau đó. Vì một số lý do, hộp Cartoon Series không được điền cho tôi để chọn phụ huynh. Đó là lý do tại sao tôi nghĩ rằng các tập phim cần phải được phân cấp. Cố gắng tìm hiểu tại sao.
Mattaton

Có, các tập phải được phân cấp để hộp meta của Cartoon Series được phổ biến.
Mattaton

Với các tập được phân cấp để tôi có thể đặt cha mẹ, url trở nên tồi tệ hơn. Với sên như bạn đề xuất, tôi nhận được tên sê-ri trong url hai lần. Vì vậy, thay vì domain/episodes/series-name/episode-namenhư trước đây, tôi đã nhận đượcdomain/episodes/series-name/series-name/episode-name
Mattaton 14/03/2015

Như tôi đã nói, các tập phim không thể được phân cấp. Tôi đã sửa đổi mã hộp meta để được điền với các loại bài không phân cấp. Sử dụng mã chính xác tôi đã đăng, tôi đã kiểm tra nó và nó đang hoạt động. Nếu bạn sử dụng mã khác, tôi không thể biết điều gì sai. Chỉ cần sao chép và dán mã từ câu trả lời và kiểm tra nó. Bạn có thể cần phải tắt plugin UI CPT hoặc, ít nhất, xóa các loại bài đăng tùy chỉnh khỏi plugin khi chúng được đăng ký trong mã.
cybmeta

Ah, lời xin lỗi của tôi, tôi đã nhanh chóng quét và nghĩ rằng phần đó là như nhau. Bạn nói đúng, trang hiện đang tải và url có vẻ chính xác.
Mattaton


-1

Bạn sẽ cần phải viết mã phân tích URL của riêng mình để biết rằng wordpress cần biết loại bài đăng mà nó cố gắng truy xuất từ ​​DB dựa trên cấu trúc url và cấu trúc url của bạn không đưa ra bất kỳ gợi ý nào cho việc này.

Đây không phải là điều rất dễ thực hiện với API quy tắc viết lại của wordpress, nhưng không có gì ngăn cản bạn bỏ qua cơ chế viết lại và tự phân tích các url. Một cái gì đó như 1. chạy quy tắc viết lại wordpress. Nếu một nội dung được tìm thấy sẽ hiển thị nội dung đó và thoát 2. lấy phần đầu tiên của url, kiểm tra xem có bài đăng nào khớp với bài đăng dự kiến ​​loại 3. vòng lặp trên các phần còn lại của URL xác minh rằng các bài đăng tồn tại và đang đúng loại 4. nếu mọi thứ phù hợp sẽ hiển thị bài đăng cuối cùng được tìm thấy, người khác sẽ hiển thị trang 404

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.