问题描述

我已经挖掘了自定义帖子类型永久链接中的每个问题,但大多数似乎是自定义分类重写的问题,或者明显缺失了 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 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。