问题描述
看起来所有的网页资源都基于删除自定义帖子类型 slug 的主题
yourdomain.com/CPT-SLUG/post-name
现在非常陈旧的解决方案通常引用了预装 WP 3.5 安装。一个常见的是:
'rewrite' => array( 'slug' => false, 'with_front' => false ),
在您的 register_post_type 功能。这不再奏效,误导了。所以我要求社区在 2017 年第一季度在 WordPress 4.7.X 的边…
从重写参数或其他任何地方,从自定义帖子类型帖子的 URL 中删除 Post Type Slug 的现代和高效方法是什么?
脚注:请通过观看/推广来支持这张 trac 票:https://core.trac.wordpress.org/ticket/34136#ticket
最佳解决方案
以下代码将会起作用,但您只需要牢记,如果您的自定义帖子类型的插件与页面或帖子的插槽相同,则冲突可能会轻松发生
首先,我们将从永久链接中删除 s::
function na_remove_slug( $post_link, $post, $leavename ) {
if ( 'events' != $post->post_type || 'publish' != $post->post_status ) {
return $post_link;
}
$post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
return $post_link;
}
add_filter( 'post_type_link', 'na_remove_slug', 10, 3 );
只是去除 s 子是不够的。现在,您将获得一个 404 页面,因为 WordPress 只期望帖子和页面的行为。您还需要添加以下内容:
function na_parse_request( $query ) {
if ( ! $query->is_main_query() || 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) {
return;
}
if ( ! empty( $query->query['name'] ) ) {
$query->set( 'post_type', array( 'post', 'events', 'page' ) );
}
}
add_action( 'pre_get_posts', 'na_parse_request' );
只需将”events” 更改为您的自定义帖子类型即可。您可能需要刷新您的固定链接。
次佳解决方案
不久之前,我试图弄清楚这一点,而我所知道的简短的答案是否定的。至少不能从重写参数内。
如果您在 wp-includes/post.php line 1454 中查看 register_post_type
的实际代码,那么长的解释变得很明显:
add_permastruct( $post_type, "{$args->rewrite['slug']}/%$post_type%", $permastruct_args );
您可以看到前缀 $ args-> 将 [‘slug’] 重写为%$ post_type%重写标记。人们可以认为 「让我们把 s just to to then then then then」「」「」「」「」「」「」until until until until until until until:::::
if ( empty( $args->rewrite['slug'] ) )
$args->rewrite['slug'] = $post_type;
您可以看到该函数总是期望一个不为空的段值,否则使用该 post 类型。
第三种解决方案
响应 my previous answer:您可以自定义 rewrite
参数到 false
注册一个新的 post 类型,并自己处理这样的重写规则
<?php
function wpsx203951_custom_init() {
$post_type = 'event';
$args = (object) array(
'public' => true,
'label' => 'Events',
'rewrite' => false, // always set this to false
'has_archive' => true
);
register_post_type( $post_type, $args );
// these are your actual rewrite arguments
$args->rewrite = array(
'slug' => 'calendar'
);
// everything what follows is from the register_post_type function
if ( is_admin() || '' != get_option( 'permalink_structure' ) ) {
if ( ! is_array( $args->rewrite ) )
$args->rewrite = array();
if ( empty( $args->rewrite['slug'] ) )
$args->rewrite['slug'] = $post_type;
if ( ! isset( $args->rewrite['with_front'] ) )
$args->rewrite['with_front'] = true;
if ( ! isset( $args->rewrite['pages'] ) )
$args->rewrite['pages'] = true;
if ( ! isset( $args->rewrite['feeds'] ) || ! $args->has_archive )
$args->rewrite['feeds'] = (bool) $args->has_archive;
if ( ! isset( $args->rewrite['ep_mask'] ) ) {
if ( isset( $args->permalink_epmask ) )
$args->rewrite['ep_mask'] = $args->permalink_epmask;
else
$args->rewrite['ep_mask'] = EP_PERMALINK;
}
if ( $args->hierarchical )
add_rewrite_tag( "%$post_type%", '(.+?)', $args->query_var ? "{$args->query_var}=" : "post_type=$post_type&pagename=" );
else
add_rewrite_tag( "%$post_type%", '([^/]+)', $args->query_var ? "{$args->query_var}=" : "post_type=$post_type&name=" );
if ( $args->has_archive ) {
$archive_slug = $args->has_archive === true ? $args->rewrite['slug'] : $args->has_archive;
if ( $args->rewrite['with_front'] )
$archive_slug = substr( $wp_rewrite->front, 1 ) . $archive_slug;
else
$archive_slug = $wp_rewrite->root . $archive_slug;
add_rewrite_rule( "{$archive_slug}/?$", "index.php?post_type=$post_type", 'top' );
if ( $args->rewrite['feeds'] && $wp_rewrite->feeds ) {
$feeds = '(' . trim( implode( '|', $wp_rewrite->feeds ) ) . ')';
add_rewrite_rule( "{$archive_slug}/feed/$feeds/?$", "index.php?post_type=$post_type" . '&feed=$matches[1]', 'top' );
add_rewrite_rule( "{$archive_slug}/$feeds/?$", "index.php?post_type=$post_type" . '&feed=$matches[1]', 'top' );
}
if ( $args->rewrite['pages'] )
add_rewrite_rule( "{$archive_slug}/{$wp_rewrite->pagination_base}/([0-9]{1,})/?$", "index.php?post_type=$post_type" . '&paged=$matches[1]', 'top' );
}
$permastruct_args = $args->rewrite;
$permastruct_args['feed'] = $permastruct_args['feeds'];
add_permastruct( $post_type, "%$post_type%", $permastruct_args );
}
}
add_action( 'init', 'wpsx203951_custom_init' );
您现在可以看到 add_permastruct
电话现在不包括 slug 了。我测试了两个场景:
- 当我创建了一个页面,其中的”calendar” 页面被覆盖的帖子类型存档,也使用”calendar” slug 。
- 当我创建了一个带有 s 子”my-event” 的页面和一个事件 (CPT) 与 s lug “my-event”,显示自定义的帖子类型。
- 任何其他页面也不工作。如果你看看上面的图片,那就很明白为什么:自定义帖子类型规则总是与一个页面插槽匹配。因为 WordPress 无法识别是否是一个页面或不存在的自定义帖子类型,它将返回 404. 这就是为什么您需要一个小块来识别页面或 CPT 。一个可能的解决方案是拦截错误并寻找可能存在 similar to this answer 的页面。
参考文献
注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。