Các loại bài tùy chỉnh lồng nhau với permalinks


9

Tôi đang cố gắng thiết lập cấu trúc loại bài đăng tùy chỉnh đa cấp với các permalinks trông giống như authors/books/chapters, với các tác giả, sách và chương đều được thiết lập làm loại bài đăng tùy chỉnh của riêng họ. Ví dụ: một URL điển hình trên trang web này có thể trông giống nhưexample.com/authors/stephen-king/the-shining/chapter-3/

Mỗi chương chỉ có thể thuộc về một cuốn sách và mỗi cuốn sách chỉ có thể thuộc về một tác giả. Tôi đã cân nhắc sử dụng các nguyên tắc phân loại thay vì CPT cho tác giả và sách, nhưng tôi cần liên kết siêu dữ liệu với từng mục và tôi thích giao diện bài đăng này.

Tôi hầu hết đều đi bằng cách đơn giản là thiết lập mỗi bài đăng tùy chỉnh như một phần tử con của một mục trong CPT một cấp. Ví dụ: tôi tạo "Chương 3" và gán "The Shining" làm cha mẹ bằng cách sử dụng hộp meta tùy chỉnh. "The Shining" lần lượt có "Stephen King" là cha mẹ. Tôi không gặp khó khăn gì khi tạo ra những mối quan hệ này.

Tôi đang sử dụng các thẻ viết lại trong sên CPT và permalinks muốn hoạt động, nhưng chúng không hoàn toàn đúng. Sử dụng một bộ phân tích viết lại, tôi có thể thấy rằng các quy tắc viết lại thực sự được tạo ra, nhưng chúng dường như không theo đúng thứ tự và vì vậy các quy tắc khác được xử lý trước.

Đây là một ảnh chụp màn hình của máy phân tích viết lại của tôi.

Đây là cách tôi đã đăng ký CPT của mình:

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

Vì vậy, có cách nào để thay đổi mức độ ưu tiên của các quy tắc viết lại của tôi để các tác giả, sách và chương đều được khớp trước?

Tôi cũng biết rằng tôi sẽ phải thêm một post_type_linkbộ lọc, nhưng điều đó dường như là thứ yếu để có được permalinks ngay từ đầu. Nếu bất cứ ai biết nơi tôi có thể tìm thấy một tổng quan toàn diện về cách bộ lọc đó hoạt động, nó sẽ được đánh giá cao.


Bạn đã xem xét chỉ sử dụng Trang? Bạn sẽ có được cấu trúc permalink đúng tự động.
Michael Hampton

Tôi chắc chắn đã xem xét nó. Vấn đề với các trang là chúng tôi có thể có 100 mục cháu cho một tác giả, điều này sẽ rất khó quản lý trong quản trị trang. Ngoài ra, chúng ta cần có thể truy vấn theo loại bài.
Dalton

Tôi đang nghiên cứu một giải pháp nhưng tôi có một câu hỏi nhanh: đó có phải là chìa khóa để có "tác giả" trước mỗi permalink không? Bởi vì đó có vẻ là stickler. Tôi nghĩ rằng nó gây nhầm lẫn cho WordPress quá nhiều, đặc biệt là vì đó là một con sên permalink cũng được sử dụng cho các trang tác giả WP. Nếu có 'tác giả' là bắt buộc, tôi nghĩ toàn bộ điều vẫn có thể làm được ... nó sẽ phức tạp hơn.
Rachel Carden

Rất tiếc, tôi đã không nhận ra rằng tác giả sẽ xung đột với sên tác giả WP tích hợp. Không, đó là không bắt buộc, nó có thể là bất cứ điều gì. Tôi cho rằng tôi cần một cái gì đó ở đó bởi vì đó là CPT, nhưng nó có thể dễ dàng trở thành "nhà văn" hoặc bất cứ thứ gì khác.
Dalton

Tôi nhận ra sự nhầm lẫn thực sự nằm ở việc chia sẻ 'tác giả' của CPT với tư cách là con sên cơ sở. Khi bạn đặt 'tác giả' là con sên cho CPT 'tác giả', sau đó bạn đặt 'tác giả /% tác giả%' cho CPT 'sách' và 'tác giả /% tác giả% /% cuốn sách%' cho các chương của CPT ' ', Sau đó, WordPress nghĩ rằng các bài đăng cho' sách 'và các bài đăng cho' chương 'là các bài đăng trẻ em theo thứ bậc theo nghĩa đen cho' tác giả '. Điều đó có ý nghĩa? Trong thử nghiệm của tôi, bạn có thể giữ 'tác giả' làm cơ sở cho CPT 'tác giả' và nó hoạt động tốt. Vì vậy, thay thế câu hỏi trước đây của tôi bằng: bạn có cần 'tác giả' hay con sên có thể bắt đầu với% tác giả% không?
Rachel Carden

Câu trả lời:


11

Nếu bạn muốn giữ 'tác giả' làm sên cơ sở trong permalinks, ví dụ example.com/authors/stephen-king/ cho 'tác giả' CPT, example.com/authors/stephen-king/the-shining/ cho CPT 'sách' và example.com/authors/stephen-king/the-shining/ch CHƯƠNG-3 / cho CPT của 'chương', WordPress sẽ nghĩ khá nhiều thứ là một bài viết của tác giả hoặc một đứa trẻ có thứ bậc của một 'tác giả 'bài đăng và, vì đó không phải là trường hợp, WordPress cuối cùng trở nên rất bối rối.

Như đã nói, có một cách giải quyết khá cơ bản nhưng miễn là cấu trúc permalink của bạn luôn tuân theo cùng một trật tự, tức là từ 'tác giả' luôn được theo sau bởi một con sên tác giả, luôn luôn đi theo một con sên cuốn sách luôn luôn đi theo bởi một chương sên, sau đó bạn nên đi.

Trong giải pháp này, không cần xác định sên viết lại trong định nghĩa loại bài đăng tùy chỉnh cho 'chương' và 'sách', nhưng đặt sên viết lại 'tác giả' đơn giản là 'tác giả', đặt mã sau vào hàm của bạn.php tập tin và "tuôn ra" các quy tắc viết lại của bạn.

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

Tìm hiểu thêm về plugin CPT-onomies


Điều này hoạt động hoàn hảo, cảm ơn bạn! Tôi cảm thấy như tôi vừa học được rất nhiều. Plugin CPT-onomies cũng rất tuyệt. wordpress.org/extend/plugins/cpt-onomies
Dalton

Tôi có cảm giác bạn có thể gặp một số trở ngại khi "thư viện" của bạn phát triển nhưng tôi đã có sẵn một số mã vì vậy, nếu bạn làm thế, hãy cho tôi biết.
Rachel Carden

@RachelCarden Bạn làm gì khi hai cuốn sách có cùng tiêu đề nhưng tác giả khác nhau? Sẽ có một sự va chạm trong URL viết lại! Làm thế nào để bạn giải quyết điều này?
Segfault

1
@Segfault Bạn sẽ phải truy xuất tất cả các sên tác giả để bạn có thể mã hóa chúng thành quy tắc viết lại: foreach ($ Author_slugs as $ Author_slug) {add_rewrite_rule ('^ tác giả /'. $ Author_slug. '/ ( ^ /] *) / ([^ /] *) /? ',' Index.php? Tác giả = '. $ Author_slug.' & ch chương = $ khớp [2] ',' top '); add_rewrite_rule ('^ tác giả /'. $ Author_slug. '/ ([^ / n / n *) /?', 'index.php? authors ='. $ Author_slug. '& Books = $ khớp với [1]', 'top') ; }
Rachel Carden

@Segfault Bạn có thể sử dụng get_terms () , nếu bạn đang sử dụng CPT-onomy hoặc get_posts () để truy xuất tên / sên bài đăng.
Rachel Carden

4

Tôi không có kinh nghiệm cá nhân với kịch bản như vậy, nhưng Randy Hoyt đã trình bày tại WordCamp San Fran vào cuối tuần trước về "Các loại bài đăng phụ" nghe giống như những gì bạn đang nói.

Đây là trang của anh ấy để nói chuyện bao gồm các slide thuyết trình của anh ấy và các liên kết đến một plugin anh ấy đã xây dựng để làm việc với các loại bài đăng phụ: http://randyhoyt.com/wordpress/subordine-post-types/


Cảm ơn, đây có vẻ là một nguồn tài nguyên tốt. Tuy nhiên, điều này không rõ liệu điều này có hỗ trợ các mối quan hệ của cháu hay không (dường như nó không có trong thử nghiệm của tôi) và nó không thực sự giúp ích cho các permalinks. Tôi đã tìm ra cách thiết lập mối quan hệ con cái / cha mẹ của mình (mặc dù đây là một cách khá hay để làm điều đó), nhưng permalinks thực sự là vấn đề tôi đang mắc kẹt bây giờ.
Dalton

1

Các quy tắc sẽ được thêm vào Extra_rules_top của WP_Rewrite theo thứ tự các phép bổ sung được thêm vào. Vì vậy, chuyển đổi thứ tự mà bạn đăng ký các loại bài đăng sẽ chuyển đổi thứ tự của các quy tắc viết lại được tạo ra làm cho chương viết lại được khớp trước. Tuy nhiên, vì bạn đang sử dụng query_var từ các post_types khác, wp_query có thể kết thúc khớp với một trong những tên đó như tên bài đăng được yêu cầu trước khi khớp với chương bạn muốn.

Tôi sẽ tạo các thẻ viết lại mới để thể hiện các trình giữ chỗ cho tác giả chính và sách gốc, tức là:

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

Khi thực hiện việc này, bạn sẽ phải lọc 'query_vars' để công khai 'Parent_book'. Sau đó, bạn sẽ cần thêm bộ lọc vào pre_get_posts sẽ chuyển đổi tên được đặt thành Parent_book query_var thành post_id và đặt nó là 'post_parent'.


Bạn có thể vui lòng cung cấp các ví dụ mã cho các bộ lọc bạn đã đề cập không? Ngoài ra, thẻ viết lại sẽ trông như thế nào đối với CPT cháu?
Dalton
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.