Bắt permalinks loại bài đăng tùy chỉnh phân cấp để hoạt động giống như các trang


16

Tôi đã tìm hiểu mọi câu hỏi ở đây trên permalinks loại bài đăng tùy chỉnh, nhưng dường như hầu hết đều là vấn đề với việc viết lại phân loại tùy chỉnh hoặc thiếu rõ ràng của flush_rewrite_rules (). Nhưng trong trường hợp của tôi, tôi chỉ sử dụng loại bài đăng tùy chỉnh (không phân loại), được đặt thành phân cấp (để tôi có thể gán mối quan hệ cha-con), với "hỗ trợ" thích hợp cho các thuộc tính metabox, v.v. Đã tuôn ra các quy tắc viết lại một ngàn cách khác nhau. Tôi đã thử các cấu trúc permalink khác nhau. Nhưng URL con luôn dẫn đến 404!

Ban đầu tôi có các loại bài đăng tùy chỉnh độc lập cho các yếu tố "cha mẹ" và "con" (sử dụng p2p) và có lẽ tôi sẽ không gặp khó khăn gì khi sử dụng phân loại cho nhóm "phụ huynh" - tôi biết chúng sẽ chính xác hơn về mặt ngữ nghĩa. Nhưng đối với khách hàng, họ dễ dàng hình dung thứ bậc nhất khi "bài đăng" được hiển thị trong quản trị viên giống như các trang: một cây đơn giản nơi trẻ em xuất hiện bên dưới cha mẹ, có tiền tố là "-" và trong trật tự thích hợp. Ngoài ra, các phương pháp khác nhau để gán thứ tự thông qua kéo-n-drop có thể được sử dụng. Nhóm thông qua phân loại (hoặc p2p) dẫn đến một danh sách "bài đăng" phẳng trong danh sách quản trị viên, điều này đơn giản là không rõ ràng về mặt trực quan.

Vì vậy, những gì tôi theo nghĩa đen là hành vi chính xác giống như các "trang" cốt lõi, nhưng với loại bài đăng tùy chỉnh của tôi. Tôi đã đăng ký loại bài đăng như mong đợi và trong quản trị viên, nó hoạt động hoàn hảo - Tôi có thể chỉ định cha mẹ và menu_order cho mỗi bản tin "bài đăng", chúng xuất hiện chính xác trong danh sách chỉnh sửa:

Spring 2012
 First Article
 Second Article

Và permalinks của họ dường như được xây dựng đúng. Trong thực tế, nếu tôi thay đổi bất cứ điều gì về cấu trúc, hoặc thậm chí thay đổi sên viết lại khi đăng ký loại bài đăng, chúng sẽ tự động cập nhật chính xác, vì vậy tôi biết có gì đó đang hoạt động:

http://mysite.com/parent-page/child-page/                  /* works for pages! */
http://mysite.com/post-type/parent-post/child-post/        /* should work? */
http://mysite.com/newsletter/spring-2012/                  /* works! */
http://mysite.com/newsletter/spring-2012/first-article/    /* 404 */
http://mysite.com/newsletter/spring-2012/second-article/   /* 404 */

Tôi cũng có các "trang" lõi tiêu chuẩn với các mối quan hệ phân cấp được tạo và chúng trông giống nhau trong quản trị viên, nhưng chúng thực sự hoạt động ở mặt trước (cả URL cha và con đều hoạt động tốt).

Cấu trúc permalink của tôi được đặt thành:

http://mysite.com/%postname%/

Tôi cũng đã thử điều này (chỉ vì rất nhiều câu trả lời khác dường như cho thấy nó là cần thiết, mặc dù nó không có ý nghĩa trong trường hợp của tôi):

http://mysite.com/%category%/%postname%/

CPT đăng ký của tôi bao gồm:

$args = array(
    'public'                => true,
    'publicly_queryable'    => true,
    'show_ui'               => true,
    'has_archive'           => 'newsletter',
    'hierarchical'          => true,
    'query_var'             => true,
    'supports'              => array( 'title', 'editor', 'thumbnail', 'page-attributes' ),
    'rewrite'               => array( 'slug' => 'newsletter', 'with_front' => false ),

Sự khác biệt duy nhất có thể nhìn thấy giữa trẻ em loại bài đăng tùy chỉnh của tôi và trẻ em trang bình thường , đó là CPT của tôi có sên ở đầu cấu trúc permalink, sau đó là sên cha / con (trong đó các trang bắt đầu bằng sên bố mẹ / con, không có "tiền tố"). Tại sao điều này sẽ hôi mọi thứ lên, tôi không biết. Rất nhiều bài báo dường như chỉ ra rằng đây chính xác là cách các permalinks CPT phân cấp như vậy nên hoạt động - nhưng của tôi, mặc dù được hình thành độc đáo, không hoạt động.

Điều cũng gây trở ngại cho tôi là khi tôi kiểm tra các truy vấn cho trang 404 đó - chúng dường như chứa các giá trị chính xác cho WP để "tìm" các trang con của tôi, nhưng có gì đó không hoạt động.

$wp_query object WP_Query {46}
public query_vars -> array (58)
'page' => integer 0
'newsletter' => string(25) "spring-2012/first-article"
'post_type' => string(10) "newsletter"
'name' => string(13) "first-article"
'error' => string(0) ""
'm' => integer 0
'p' => integer 0
'post_parent' => string(0) ""
'subpost' => string(0) ""
'subpost_id' => string(0) ""
'attachment' => string(0) ""
'attachment_id' => integer 0
'static' => string(0) ""
'pagename' => string(13) "first-article"
'page_id' => integer 0
[...]

Tôi đã thử điều này với nhiều chủ đề khác nhau, bao gồm hai mươi mười hai, chỉ để chắc chắn rằng đó không phải là một số mẫu bị thiếu trong phần của tôi.

Sử dụng Trình kiểm tra quy tắc Rewrite, đây là nội dung hiển thị cho url: http://mysite.com/newsletter/spring-2012/first-article/

newsletter/(.+?)(/[0-9]+)?/?$   
       newsletter: spring-2012/first-article
           page: 
(.?.+?)(/[0-9]+)?/?$    
       pagename: newsletter/spring-2012/first-article
           page: 

Làm thế nào nó hiển thị trên một trang thanh tra khác:

RULE:
newsletter/(.+?)(/[0-9]+)?/?$
REWRITE:
index.php?newsletter=$matches[1]&page=$matches[2]
SOURCE:
newsletter

Đầu ra viết lại này sẽ khiến tôi tin rằng permalink "không đẹp" sau đây sẽ hoạt động:

http://mysite.com/?newsletter=spring-2012&page=first-article

Nó không 404, nhưng nó hiển thị "bản tin" của mục CPT, không phải cho trẻ em. Yêu cầu trông như thế này:

Array
(
    [page] => first-article
    [newsletter] => spring-2012
    [post_type] => newsletter
    [name] => spring-2012
)

Câu trả lời:


15

Đây là lần đầu tiên tôi tham gia vào Stack Exchange, nhưng tôi sẽ thử và xem liệu tôi có thể giúp bạn đi đúng hướng hay không.

Theo mặc định, CPT phân cấp hoạt động chính xác theo cách bạn đã mô tả. Tiền tố sên duy nhất, "bản tin" trong trường hợp này, là để cho công cụ viết lại biết cách phân biệt các yêu cầu cho các loại bài đăng khác nhau.

Các đăng ký CPT đó có vẻ ổn, nhưng khi CPT được yêu cầu, pagenamevar truy vấn không nên có giá trị và namevar truy vấn phải giống như newsletterở đây, do đó có vẻ như có xung đột ở đâu đó trong thiết lập của bạn.

Để giúp gỡ lỗi, hãy cài đặt và kích hoạt Plugin Trình kiểm tra quy tắc viết lại , sau đó truy cập màn hình tại " Công cụ -> Quy tắc ghi lại ".

  1. Trong khi xem danh sách, tất cả các quy tắc của bạn cho CPT bản tin phải được liệt kê trước bất kỳ quy tắc viết lại trang nào . Xác minh đây là trường hợp bằng cách quét cột " Nguồn ".
  2. Nếu kiểm tra, hãy nhập URL cho CPT "bài viết đầu tiên" của bạn trong trường " Kết hợp URL " và nhấp vào nút "Bộ lọc" để xem quy tắc nào phù hợp. Nó phải phù hợp với quy tắc bản tin và quy tắc trang, nhưng quy tắc bản tin nên là đầu tiên.

Nếu điều đó không tiết lộ bất kỳ vấn đề nào, hãy tìm kiếm post_namecột trong wp_postsđể tìm các bài đăng khác với sên "bài viết đầu tiên" để xem liệu có thể có xung đột hay không. Thực hiện tìm kiếm "bản tin" là tốt, chỉ để chắc chắn.

Thêm đoạn mã sau để kiểm tra các vars truy vấn của bạn sớm trong yêu cầu kiểm tra và xem những đoạn nào đang được đặt bởi khớp quy tắc viết lại (truy cập CPT con ở mặt trước). Nếu pagenamevar không xuất hiện ở đây, thì nó sẽ được đặt bởi một cái gì đó sau này trong yêu cầu:

add_filter( 'request', 'se77513_display_query_vars', 1 );

function se77513_display_query_vars( $query_vars ) {
    echo '<pre>' . print_r( $query_vars, true ) . '</pre>';

    return $query_vars;
}

Bất kỳ plugin / hàm nào sửa đổi các vars truy vấn đều có thể gây ra xung đột, vì vậy hãy vô hiệu hóa chúng nếu bạn vẫn thấy có vấn đề. Đồng thời xóa quy tắc viết lại của bạn sau mỗi bước, đặc biệt nếu yêu cầu khớp với quy tắc sai trong bước thứ hai ở trên (giữ màn hình "Permalinks" mở trong một tab riêng và chỉ cần làm mới nó).


Tôi đã chỉnh sửa câu hỏi để hiển thị đầu ra từ trình kiểm tra quy tắc viết lại, vì những nhận xét này không cho phép đủ định dạng. Các quy tắc cho CPT không hiển thị ở đầu danh sách, trước mọi thứ khác - nhưng không chắc chắn quy tắc nào dưới đây là quy tắc "trang" (không rõ ràng). Ngoài ra, không có va chạm trong post_namecột.
soma

Bạn có suy nghĩ gì về cấu trúc permalink thích hợp không? Tôi đã quay trở lại /%postname%/kể từ khi /%category%/chỉ bao gồm dường như nhầm lẫn mọi thứ hơn nữa trong thanh tra viết lại. Tôi thậm chí đã thấy mọi người tuyên bố rằng /%category%/ánh xạ kỳ diệu cho CPT có nghĩa là "cha mẹ", mặc dù tôi không thấy điều này là đúng.
soma

Đầu ra đó dường như xuất hiện cho một plugin khác, đó là lý do tại sao bạn không thấy "nguồn" của quy tắc. Dù bằng cách nào, có vẻ như quy tắc của bạn phù hợp với tốt. Tôi đã chỉnh sửa câu trả lời của mình để bao gồm một đoạn mã để kiểm tra các vars truy vấn trước đó trong yêu cầu để đảm bảo chúng được đặt chính xác.
Brady Vercher

Đối với cấu trúc permalink, tôi không phải là người hâm mộ bao gồm cả thể loại. Nó chỉ là một phần chuyển động khác mà không giúp được gì, và bài viết có thể thuộc nhiều danh mục. Nếu có bất kỳ cơ hội nào mà bạn có thể thay đổi cấu trúc permalink trong tương lai hoặc muốn CPT khác tải mà không có tiền tố sên, tôi khuyên bạn nên "đặt tên" cấu trúc của mình bằng một cái gì đó cố định và duy nhất /blog/%postname%/.
Brady Vercher

đó là plugin phù hợp, nhưng có hai trang: "viết lại phân tích" và "viết lại quy tắc", cả hai đều cung cấp một URL kiểm tra. Tôi đã thử trang khác và nó đã hiển thị nguồn là "chương trình" cho nhóm thụt đầu tiên và "trang" cho nhóm thứ hai.
soma

5

Các parent/Childpermalink Tác phẩm ra khỏi hộp miễn là bạn thiết lập

'hierarchical'=> true,
'supports' => array('page-attributes' ....

Cập nhật:

Tôi vừa thử nghiệm lại và nó hoạt động như mong đợi, với trường hợp thử nghiệm này:

add_action('init','test_post_type_wpa77513');
function test_post_type_wpa77513(){
    $args = array(
        'public' => true,
        'publicly_queryable' => true,
        'show_ui' => true, 
        'show_in_menu' => true, 
        'query_var' => true,
        'rewrite' => true,
        'capability_type' => 'post',
        'has_archive' => true, 
        'hierarchical' => true,
        'supports' => array( 'title', 'editor', 'thumbnail', 'page-attributes' )
    ); 

    register_post_type( 'newsletter', $args );
}

và permalink được đặt thành /%postname%/Tôi nhận được bản tin / phụ huynh / trẻ em làm việc tốt.


Mã của tôi ở trên không hiển thị nó, nhưng tôi có page-attributeshỗ trợ (điều này thực sự chỉ là hiển thị metabox để gán cha mẹ, không nên ảnh hưởng đến permalinks) - nhưng nhận được 404. Cấu trúc permalink nào cần được thiết lập? hay nó có vấn đề?
soma

@somatic tôi chỉ thử nghiệm lại và nó hoạt động tốt, vì permalink tôi không chắc nó có quan trọng không, nhưng bất cứ cách nào tôi đều cập nhật câu trả lời của mình.
BaiNET

Tôi có thể xác nhận rằng, với việc bổ sung một mảng đối số cho 'nhãn' (không có CPT sẽ không xuất hiện trong quản trị viên), ví dụ cơ bản này hoạt động trên bản cài đặt WP3 của van3 với mười hai lần. Nhưng tôi nhận thấy một vài điểm khác biệt chính trong register_post_type$ args của bạn : Tôi đã sử dụng 'rewrite' => array( 'slug' => 'newsletter', 'with_front' => false ), nơi bạn đã sử dụng true. Bạn cũng chỉ đơn giản là thông qua truecho has_archive, nơi tôi đã thông qua sên. Tuy nhiên, khi tôi khớp với các đối số của bạn, tôi vẫn nhận được 404 ... Vẫn đang cố gắng theo dõi xem tôi đang sai ở đâu.
soma

3

Ngoài việc hỏi »Bạn đã thử tắt và bật lại chưa?« , Tôi cũng phải hỏi "Bạn có bất kỳ plugin nào hoạt động không và Chủ đề của bạn có làm gì với permalinks không (ví dụ: đăng ký phân loại, đăng loại, thêm quy tắc viết lại , Vân vân.)?

Nếu vậy: Điều này vẫn xảy ra, sau khi bạn tắt tất cả các plugin và chuyển sang TwentyEleven? nhập mô tả hình ảnh ở đây

Để gỡ lỗi thêm, hãy truy cập GitHub và lấy Plugin "Rewrite" của Toschos . Sau đó chuyển sang repo plugin chính thức trên wp.org và grap Plugin MonkeyManRewriteAnalyzer . Tôi thậm chí đã viết một phần mở rộng để dán cả hai một chút với nhau. Điều này sẽ cung cấp cho bạn rất nhiều chi tiết về thiết lập của bạn.


tốt, nếu tôi vô hiệu hóa mọi thứ , tôi sẽ không có loại bài đăng tùy chỉnh đó là điểm của câu hỏi này ... nhưng vâng, tôi đã thử ngay cả với hai mươi chủ đề. Tôi vẫn đang đào qua một vài phích cắm cần thiết để xem những gì đang xáo trộn truy vấn, vì từ những gì tôi có thể thấy, các permalinks được hình thành rõ ràng.
soma

@somatic Tất nhiên là không vô hiệu hóa bạn :)
kaiser

@somatic Xem cập nhật.
kaiser

1

Vì vậy, sau khi xác nhận rằng tôi có thể có được hành vi trang phân cấp dự kiến ​​với cài đặt hoàn toàn sạch và chỉ cần một tuyên bố CPT, tôi biết lỗi nằm ở đâu đó trong plugin của mình mà tôi sử dụng để xử lý việc tạo CPT (rất phức tạp, xử lý các siêu dữ liệu tùy chỉnh, phân loại , Vân vân). Vấn đề là, mặc dù tất cả các lời khuyên để kiểm tra viết lại hoặc các vấn đề truy vấn, tôi không thể thấy bất cứ điều gì rõ ràng sai. Tôi đã kiểm tra mọi bộ lọc và hook, xem truy vấn tại mỗi điểm và không thấy điều gì có thể gây ra 404.

Vì vậy, tôi được giao nhiệm vụ vô hiệu hóa / kích hoạt thủ công cho mỗi 9 lớp lớn, và sau đó, tìm thấy ít nhất 2 trong số chúng gây ra 404, lần lượt đi qua từng chức năng và vô hiệu hóa / kích hoạt chúng, sau đó lần theo dấu vết theo dòng trong các chức năng đó - một nỗ lực vũ phu để xem chính xác điều gì đã gây ra 404, ngay cả khi tôi không biết tại sao.

Đó là khi tôi thấy có một hậu quả của việc sử dụng $query->get_queried_object(). Có vẻ như sử dụng hàm bao bọc này thực sự sửa đổi chính truy vấn $, mà tôi nghĩ rằng tôi đã trả lại không thay đổi khi kết thúc chức năng của mình. Ba bộ lọc qua 2 lớp đã tham gia mà sửa đổi truy vấn: parse_query, posts_orderby, posts_join- và tất cả các chức năng gọi lại được gọi $query->get_queried_object()vào thông qua $queryarg để sau đó chạy một số xét nghiệm có điều kiện và đôi khi sửa đổi các truy vấn vars (như đối với trường hợp thứ tự sắp xếp đặc biệt). Thật kỳ lạ, các chức năng này thực sự hoạt động tốt với những gì chúng được thiết kế để làm, mặc dù tôi sử dụng chức năng này. Tôi chưa bao giờ nhận thấy bất cứ điều gì sai với truy vấn $ được trả về trước đây!

Bằng cách nào đó, sau hơn một năm phát triển và sử dụng trên hàng chục trang web sản xuất trực tiếp, tôi chưa bao giờ gặp phải bất kỳ tác động bất lợi nào từ sai lầm này. Chỉ khi tôi mạo hiểm vào các CPT phân cấp, sự khác biệt nhỏ này mới đột nhiên phá vỡ mọi thứ. Đó là một phần trong những điều khiến tôi rất khó khăn với điều này - như tôi có thể nói, bộ lọc truy vấn của tôi rất đáng tin cậy!

Tôi thú nhận rằng tôi vẫn không biết chính xác lý do tại sao việc gọi chức năng này chỉ phá vỡ một khía cạnh nhỏ này của các trang con CPT - và chưa bao giờ biểu hiện bất kỳ vấn đề nào khác! Nhưng rõ ràng là sử dụng nó trong một cuộc gọi lại bộ lọc đã xử lý được trả lại $querybằng cách nào đó. Bằng cách loại bỏ cuộc gọi này, lỗi 404 của tôi biến mất.

Cảm ơn tất cả các lời khuyên - ước gì tôi có thể chia tiền thưởng, vì tôi đã hiểu rõ hơn từ mỗi câu trả lời, ngay cả khi giải pháp cuối cùng có phần không liên quan. Đây là một bài học giáo dục về việc không tin tưởng một cách mù quáng mã của bạn, ngay cả khi nó hoạt động với bạn một cách đáng tin cậy trong một thời gian dài, hoặc nó không tạo ra bất kỳ lỗi rõ ràng nào.

Đôi khi, như biểu đồ của kaiser rất hiện thân, bạn chỉ cần bắt đầu ném công tắc cho đến khi đèn bật lại. Trong trường hợp của tôi, tôi đã phải thực hiện chiến lược khắc phục sự cố tương tự cho đến từng dòng riêng lẻ trong một chức năng trước khi tôi có thể thấy vấn đề.


Bạn cũng có thể sử dụng chức năng bao bọc get_queried_object()mà không chặn $wpdbđối tượng.
kaiser

Nhưng cái $querynào lấy? Tôi đang sử dụng bộ lọc này trong một bộ lọc cho parse_queryvà cần đặc biệt lấy đối tượng được truy vấn của một cụ thể $queryđược truyền từ bộ lọc ...
somatic

Tôi vừa thử sử dụng trình bao bọc bên trong bộ lọc của mình parse_query. Nó gây ra lỗi 404 tương tự một lần nữa. Tôi phải tìm cách tái tạo những gì get_queried_object()không cần làm hỏng các bộ lọc này ...
somatic

-2

Bạn đang chạy phiên bản mới nhất của WP? Tôi đoán đó là câu hỏi đầu tiên (như khi bạn gọi cho bộ phận hỗ trợ kỹ thuật và họ hỏi bạn rằng máy tính của bạn đã được cắm chưa!), Vì tôi đã đọc rằng vấn đề này đã được giải quyết trong bản cập nhật phiên bản mới nhất.

Có một bài đăng trên digwp.com giải quyết vấn đề này (http://digwp.com/2011/06/dont-use-postname/). Rõ ràng WP không thể dễ dàng phân biệt sự khác biệt giữa các bài đăng và trang và nếu bạn bắt đầu các url của mình bằng tùy chọn dựa trên văn bản, WP sẽ kích hoạt một cờ tạo quy tắc cho mỗi trang / bài đăng mà bạn có. Nếu bạn có nhiều nội dung trên trang web của mình, điều đó có thể dẫn đến một số lượng lớn yêu cầu và máy chủ của bạn có thể sẽ hết thời gian, điều này sẽ dẫn đến một loạt 404 ngay cả khi các trang ở đó.

Vì thế. Nếu trước tiên bạn sử dụng cấu trúc dựa trên số, thì cấu trúc dựa trên văn bản của bạn, tôi muốn rằng vấn đề 404 của bạn sẽ được giải quyết. Bây giờ, xem xét các vấn đề SEO, tôi sẽ không sử dụng cấu trúc ngày, nhưng đưa ra quyết định đó sẽ đủ logic cho bạn.


2
Tôi đang trên 3,5. Kể từ WP3.3.1, sự cố này trên digiwp đã được khắc phục.
soma
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.