WordPress使用一组重写规则将url转换为数据库查询。
处理页面URL的正则表达式非常通用,IIRC类似(.+.?)/?
, 事实上,一切都还没有被其他规则所匹配。
因此,无法编写适用于您的情况的重写规则:因为您无法通过regex区分url中的example.com/my-portal/sample-page
“我的门户”部分是CPT和sample-page
是一页。
如果嵌套级别更高,事情就会变得更复杂:my-portal/my-portal-child/sample-page
.
为了处理这种URL,WordPress使用get_page_by_path()
功能:将页面url分解为/
, 获取页段塞,然后查询数据库中的所有pages 有鼻涕虫的。
E、 g如果您有一个slug为“sample page”的页面,并且您将其设置为父页面,则CPT“my portal”会调用:
get_page_by_path(\'my-portal/sample-page\')
但是它
doesn\'t 返回任何结果,因为它查找具有slug“sample page”且其父级为另一个的页面
page 使用slug“我的门户”。该页面不存在,因此出现404错误。
然而get_page_by_path()
接受post类型数组作为第三个参数:如果将其设置为array(\'page\', \'portal\')
然后,该函数将能够正确找到页面。
因此,您可以通过手动将页面id(如上所述检索)设置到WP查询变量中来解决此问题。
这个\'parse_request\'
挂钩适用于以下范围:
它在解析url后运行,并传递给挂接回调实例$wp
对象可用于设置查询变量代码:
add_action(\'parse_request\', function ($wp) {
// only if WP found a page
if (isset($wp->query_vars[\'pagename\']) && ! empty($wp->query_vars[\'pagename\'])) {
$page = get_page_by_path( // let\'s find the page object
$wp->query_vars[\'pagename\'],
OBJECT,
array(\'page\', \'portal\') // we need to set both post types
);
if ($page instanceof WP_Post) { // if we find a page
unset($wp->query_vars[\'pagename\']); // remove pagename var
$wp->query_vars[\'page_id\'] = $page->ID; // replace with page_id query var
}
}
});
这段代码,再加上OP中的过滤器,就是您所需要的全部。
请注意,代码甚至可以与嵌套的分层门户一起使用。