在我的主题中,我创建了一个新的自定义帖子类型webinar
. 因为我们只发布了1条webinar
每月,我们希望使用permalink结构-
/webinar/%year%/%monthnum%/
我们不使用的地方
/%day%/
和/或
/%postname%/
这可能吗?
当前它显示为一个月存档,其中
/webinar/2018/08/
有标题
Archives for August 2018
不仅仅是一个帖子
<小时>Attributes:
WordPress(4.9.8)
Genesis框架(2.6.1)
Dynamic主题(2.3.1)
https://cobaltapps.com
我正在使用自定义帖子类型UI插件创建我的自定义帖子类型-https://wordpress.org/plugins/custom-post-type-ui/
它自动生成以下代码-
function cptui_register_my_cpts_webinars() {
/**
* Post Type: Webinars.
*/
$labels = array(
"name" => __( "Webinars", "" ),
"singular_name" => __( "Webinar", "" ),
"menu_name" => __( "UDEO Webinars", "" ),
"all_items" => __( "All Webinars", "" ),
"add_new" => __( "Add New", "" ),
"add_new_item" => __( "Add New Webinar", "" ),
"edit_item" => __( "Edit Webinar", "" ),
"new_item" => __( "New Webinar", "" ),
"view_item" => __( "View Webinar", "" ),
"view_items" => __( "View Webinars", "" ),
"search_items" => __( "Search Webinar", "" ),
"not_found" => __( "No Webinars Found", "" ),
"not_found_in_trash" => __( "No Webinars found in Trash", "" ),
"archives" => __( "Webinar Archives", "" ),
);
$args = array(
"label" => __( "Webinars", "" ),
"labels" => $labels,
"description" => "",
"public" => true,
"publicly_queryable" => true,
"show_ui" => true,
"show_in_rest" => false,
"rest_base" => "",
"has_archive" => false,
"show_in_menu" => true,
"show_in_nav_menus" => true,
"exclude_from_search" => false,
"capability_type" => "post",
"map_meta_cap" => true,
"hierarchical" => false,
"rewrite" => array( "slug" => "webinars", "with_front" => true ),
"query_var" => true,
"supports" => array( "title", "editor", "thumbnail", "custom-fields", "comments", "author" ),
);
register_post_type( "webinars", $args );
}
add_action( \'init\', \'cptui_register_my_cpts_webinars\' );
最合适的回答,由SO网友:Milo 整理而成
我不确定您现有的设置是如何工作的,因为我无法使用默认的216th主题的代码复制月/年归档行为,然而,解决方案可能是相同的,但可能不是。
首先,我建议不要使用年/月的发布后日期,这只会限制您的灵活性。我将使用post元数据在键下存储年份和月份webinar_year
和webinar_month
. 如果想让最终用户使用起来更简单,可以为它们添加一个自定义的元框,还可以挂接到保存后过程并引入一些自动化。
因此,第一步是添加几个新的重写标记,并为您的帖子类型定义一个新的permastruct-
function cptui_register_my_cpts_webinars() {
// your existing post type registration code
// $args, etc..
register_post_type( "webinars", $args );
add_rewrite_tag( \'%webinar_year%\', \'([0-9]{4})\' );
add_rewrite_tag( \'%webinar_month%\', \'([0-9]{2})\' );
add_permastruct( \'webinars\', \'webinar/%webinar_year%/%webinar_month%/\' );
}
add_action( \'init\', \'cptui_register_my_cpts_webinars\' );
添加后,不要忘记刷新重写规则。
然后,您需要在post链接上使用一个过滤器来替换webinar_year
和webinar_month
占位符的元值-
function webinars_permalink( $post_link, $post ) {
if( \'webinars\' == $post->post_type ) {
$webinar_year = ( ! get_post_meta( $post->ID, \'webinar_year\', true ) ) ? \'0000\' : get_post_meta( $post->ID, \'webinar_year\', true );
$webinar_month = ( ! get_post_meta( $post->ID, \'webinar_month\', true ) ) ? \'00\' : get_post_meta( $post->ID, \'webinar_month\', true );
$post_link = str_replace( [\'%webinar_year%\', \'%webinar_month%\'], [$webinar_year, $webinar_month], $post_link );
}
return $post_link;
}
add_filter( \'post_type_link\', \'webinars_permalink\', 10, 2 );
现在,您应该能够创建这些帖子,并看到替换了年和月值的正确URL。但当你去拜访他们时,他们仍然不起作用。
这些请求目前对WordPress来说毫无意义,因此我们需要拦截它们,找出它们的目的,然后更正查询,以便WordPress能够找到它。我们在打开过滤器的情况下执行此操作request
, 在WordPress决定查询的目的之前提前触发-
function webinars_request( $request ) {
if( isset( $request[\'webinar_year\'] ) && isset( $request[\'webinar_month\'] ) ){
$webinar = new WP_Query([
\'post_type\' => \'webinars\',
\'posts_per_page\' => 1,
\'meta_query\' => [
[
\'key\' => \'webinar_year\',
\'value\' => $request[\'webinar_year\']
],
[
\'key\' => \'webinar_month\',
\'value\' => $request[\'webinar_month\']
]
]
]);
if( $webinar->have_posts() ){
$request[\'post_type\'] = \'webinars\';
$request[\'webinars\'] = $webinar->post->post_name;
$request[\'name\'] = $webinar->post->post_name;
}
}
return $request;
}
add_filter( \'request\', \'webinars_request\' );
这里我们只查询一篇带有匹配元键/值的帖子。它将返回最新的一个,其中包含请求的值,因此这里的唯一性是由您来执行的。
不,这不是最优雅的。WordPress只将post slug视为唯一的标识单一post查询的对象,因此,您想要在其中插入的任何其他内容都需要手动完成。