問題描述
看起來所有的網頁資源都基於刪除自定義帖子類型 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 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。

