問題描述

我已經挖掘了自定義帖子型別永久連結中的每個問題,但大多數似乎是自定義分類重寫的問題,或者明顯缺失了 flush_rewrite_rules() 。但是在我的情況下,我只使用自定義的帖子型別 (沒有分類),設定為層次結構 (所以我可以分配 parent-child 關係),適用於屬性 metabox 等的”support” 等。我重新整理了重寫規則有千種不同的方式。我嘗試過不同的永久連結結構。但是,小孩的 URL 總是導致 404!

我原來擁有”parent” 和”child” 元素 (使用 p2p) 的獨立自定義帖子型別,我可能沒有使用”parental” 分組的分類法,我知道這些在語義上更準確。但是對於客戶端來說,當管理員中顯示”posts” 時,可以看到層次結構是最簡單的,就像頁面一樣:一個簡單的樹,其中孩子出現在父級下方,以”–“ 為字首,並以正確的順序。此外,可以使用透過 drag-n-drop 分配順序的各種方法。透過分類法 (或 p2p) 進行分組可以在管理列表中建立一個”posts” 的平面列表,這根本不是視覺上顯而易見的。

所以我以後是字面上與核心”pages” 完全相同的行為,但與我的自定義帖子型別。我已經按照預期的方式註冊了帖子型別,並且在管理員中它完美地工作 – 我可以為每個通訊”post” 分配一個父母和一個 menu_order,它們在編輯列表中正確顯示:

Spring 2012
— First Article
— Second Article

而他們的固定連結似乎正確構建。事實上,如果我改變任何關於結構的東西,甚至在註冊帖子型別時改變重寫外掛,他們會自動更新,所以我知道一些工作:

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 */

我也有標準的核心”pages”,建立了層次關係,並且它們在管理中看起來是一樣的,但是它們實際上也是在 front-end 上工作的 (父級和子級 URL 都可以正常工作) 。

我的永久連結結構設定為:

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

我也嘗試過這個 (因為很多其他答案似乎表明它是必需的,雖然在我的情況下沒有意義):

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

我的註冊 CPT 認為包括:

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

我的自定義帖子型別的孩子和正常頁面的孩子之間唯一可見的區別是,我的 CPT 在永久連結結構的開始有 s,,then,,,,,,,,,,,,,,,,,,,,,,,無”prefix”) 。為什麼這會造成事情呢,我不知道。大量的文章似乎表明,這正是這樣一個等級的 CPT 固定連結應該如何行事 – 但是我的儘管形式很好,但是不起作用。

當我檢查這個 404 頁面的 query_vars 時,還有什麼讓我感到困惑的是,它似乎包含 WP 到”find” 我的子頁面的正確值,但是沒有辦法。

$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
[...]

我已經嘗試過各種主題,包括二十二,只是為了確保它不是一些缺少的模板我的部分。

使用重寫規則檢查器,這是顯示的 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:

它如何顯示在另一個檢查器頁面上:

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

這個重寫輸出將導致我相信以下”non-pretty” 固定連結將工作:

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

它不是 404,但它顯示父 CPT 專案”newsletter”,而不是孩子。請求如下所示:

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

最佳解決方案

這是我第一次參加 Stack Exchange,但是我會去看看我是否可以幫助你指出正確的方向。

預設情況下,分級 CPT 的行為與您所描述的方式完全相同。在這種情況下,獨特的 slug 字首”newsletter” 是讓重寫引擎知道如何分離不同的 post 型別的請求。

那些 CPT 註冊參考看起來很好,但是當請求 CPT 時,pagename 查詢 var 不應該有一個值,並且 name 查詢 var 應該與 newsletter 在這裡相同,所以看起來你的設定中有一個衝突。

要幫助除錯,安裝和啟用 Rewrite Rules Inspector Plugin,然後訪問螢幕上的 「工具 – > 重寫規則」 。

  1. 在檢視列表時,您的所有 CPT 通訊規則都應該在任何頁面重寫規則之前列出。透過掃描”Source” 列來驗證是這樣的。

  2. 如果簽出,請在”Match URL” 欄位中輸入”first-article” CPT 的 URL,然後單擊”Filter” 按鈕檢視哪個規則匹配。它應該匹配通訊規則和頁面規則,但是通訊規則應該是第一個。

如果沒有顯示任何問題,請搜尋 wp_posts 中的 post_name 列以查詢”first-article” slug 的其他帖子,看看是否有衝突。也可以搜尋”newsletter”,只是為了確保。

新增以下程式碼片段,以便在請求早期檢查您的查詢變數,以檢查哪些是由重寫規則匹配設定的 (請訪問前端的子級 CPT) 。如果 pagename 變數不出現在這裡,那麼它將在以後的請求中被設定:

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

修改查詢 vars 的任何外掛/函式可能會導致衝突,因此如果仍然看到問題,請停用它們。還要在每一步之後重新整理重寫規則,特別是如果請求在上述第二步中匹配錯誤的規則 (保持”Permalinks” 螢幕在單獨的選項卡中開啟,只需重新整理它) 。

次佳解決方案

parent/Child 永久連結只要您設定,即可開箱即用

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

更新:

我剛剛測試了它,它的工作原理如下:在這個測試案例中:

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

和永久連結設定為/%postname%/我得到通訊/父/子工作正常。

第三種解決方案

除了詢問» 你是否嘗試關閉它?「,我還要問」 你有任何外掛是活動的,是你的主題做任何事情的永久連結 (例如:註冊分類,帖子型別,新增重寫規則等)?

如果是這樣:這是否仍然發生,您停用所有外掛並切換到 TwéEleven?

要進一步除錯,請轉到 GitHub 並抓取 Toschos “Rewrite” Plugin 。然後切換到官方外掛 repo on wp.org and grap the MonkeyManRewriteAnalyzer Plugin 。我甚至寫了一點點擴充套件,粘合在一起。這將給你很多關於你的設定的細節。

參考文獻

注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。