WordPress使用重写规则来解析请求。这意味着,如果请求与其中一条规则匹配,则将使用该规则对其进行解析。
页面规则是为捕获大多数与任何早期规则都不匹配的请求而制定的最后一条规则之一。所以,如果您添加没有任何slug的CPT,那么页面规则将不会启动。。。
解决这个问题的一种方法是用slug注册CPT,然后更改它们的链接和WPs行为。代码如下:
function register_mycpt() {
$arguments = array(
\'label\' => \'MyCPT\',
\'public\' => true,
\'hierarchical\' => false,
...
\'has_archive\' => false,
\'rewrite\' => true
);
register_post_type(\'mycpt\', $arguments);
}
add_action( \'init\', \'register_mycpt\' );
现在,这些帖子的URL如下所示:
http://example.com/mycpt/{post_name}/
但我们可以使用
post_type_link
过滤器:
function change_mycpt_post_type_link( $url, $post, $leavename ) {
if ( \'mycpt\' == $post->post_type ) {
$url = site_url(\'/\') . $post->post_name . \'/\';
}
return $url;
}
add_filter( \'post_type_link\', \'change_mycpt_post_type_link\', 10, 3 );
现在URL将是正确的,但是。。。他们不会工作的。它们将使用页面重写规则进行解析,并将导致404错误(因为没有包含此类URL的页面)。但我们也可以解决这个问题:
function try_mycpt_before_page_in_parse_request( $wp ) {
global $wpdb;
if ( is_admin() ) return;
if ( array_key_exists( \'name\', $wp->query_vars ) ) {
$post_name = $wp->query_vars[\'name\'];
$id = $wpdb->get_var( $wpdb->prepare(
"SELECT ID FROM {$wpdb->posts} WHERE post_type = %s AND post_name = %s ",
\'mycpt\', $post_name
) );
if ( $id ) {
$wp->query_vars[\'mycpt\'] = $post_name;
$wp->query_vars[\'post_type\'] = \'mycpt\';
}
}
}
add_action( \'parse_request\', \'try_mycpt_before_page_in_parse_request\' );
附:使用该代码明智吗?这是另一个问题。它在很大程度上改变了WP的行为,所以可能有点棘手。但如果真的有需要,你可以这样做。。。
免责声明:此代码对于非层次化CPT很好,但您也可以对其进行调整以适用于层次化CPT。。。