为什么后缀会附加到(某些)数字贴子段塞中,WordPress贴子几乎总是有数字永久对齐,例外情况是它们可能与其他贴子、提要或post
post type日期存档,或以其他方式保留。这个wp_unique_post_slug()
函数通过附加后缀来缓解这些冲突。
当数字%postname%
满足以下三个条件之一:
/*
* Potential date clashes are as follows:
*
* - Any integer in the first permastruct position could be a year.
* - An integer between 1 and 12 that follows \'year\' conflicts with \'monthnum\'.
* - An integer between 1 and 31 that follows \'monthnum\' conflicts with \'day\'.
*/
所以,当使用
/%postname%/
单独作为永久链接结构,数字帖子名总是会产生附加的slug,因为WordPress认为这些slug代表一年的存档-这是使用更健壮的永久链接结构的一个很好的理由。
你可能会争辩说,WordPress不需要解释从0到博客开始的年份,甚至可能是现在的数百年或数百万年。然而,在考虑这些不太可能的情况时,代码没有对环境或配置做出任何假设(用户可以将其系统配置为“1”,或者发布日期为数千年后的帖子,以强化虚构的知识),这可以说是一种更负责任的方法。
解决方案从4.3.1开始,WordPress的行为将保持不变,因为它是以某种方式预先设置的基于日期的帖子存档的“基础”,就像对自定义帖子类型所做的那样。因此,唯一直接的解决办法是使用/%postname%/
对于permalink结构(例如,静态非数字前缀:/blog/%postname%/
. 或添加帖子的类别:/%category%/%postname%/
).
或者,手动将任何非数字、URL友好的字符添加到每个帖子的slug中,可以防止添加后缀。
所有其他解决方案都变得有些“黑客”,因为它们不再利用WordPress的核心行为来解决问题,而是尝试通过以不寻常且经常复杂的方式应用工具来解决问题。
例如,您可以使用\'wp_unique_post_slug\'
筛选以忽略不太可能的冲突:
// Make some "reasonable" assumptions about the dates of this blog\'s content.
// These assume standard date & time settings for the host.
define( \'REASONABLE_YEAR_ARCHIVE_LOWER\', 2003 ); // Unlikely that this blog published content before WP\'s initial release.
define( \'REASONABLE_YEAR_ARCHIVE_UPPER\', 3000 ); // Probably won\'t publish content after/with the year 3000.
add_filter( \'wp_unique_post_slug\', \'wpse_210487_reasonably_unique_post_slug\', 10, 6 );
/**
* If WordPress modified a post-slug to avoid conflicts with date archives when
* %postname% is the first permastruct, undo the modification if the slug is an
* "unreasonable" year. NOTE: this is a hack, and has a high potential for
* introducing new bugs, particularly after the year
* REASONABLE_YEAR_ARCHIVE_UPPER.
*/
function wpse_210487_reasonably_unique_post_slug( $slug, $post_ID, $post_status, $post_type, $post_parent, $original_slug ) {
global $wpdb, $wp_rewrite;
$permastructs = array_values( array_filter( explode( \'/\', get_option( \'permalink_structure\' ) ) ) );
// Don\'t re-process the slug if:
if( \'post\' !== $post_type // - the item is not a \'post\'
|| $original_slug === $slug // - the item\'s slug was not altered to resolve a conflict
|| 0 !== array_search( \'%postname%\', $permastructs ) // - the permalink structure does not start with %postname%
|| ! preg_match( \'/^[0-9]+$/\', $slug ) // - the slug is not strictly numeric
)
return $slug;
// If the original slug conflicted with another post, use the WordPress-altered slug
$check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type = %s AND ID != %d LIMIT 1";
$post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $original_slug, $post_type, $post_ID ) );
if( $post_name_check )
return $slug;
// If the original slug conflicted with a feed, use the WordPress-altered slug
if ( is_array( $wp_rewrite->feeds ) && in_array( $original_slug, $wp_rewrite->feeds ) )
return $slug;
// If the original slug was otherwise reserved, use the WordPress-altered slug
if( apply_filters( \'wp_unique_post_slug_is_bad_flat_slug\', false, $original_slug, $post_type ) )
return $slug;
// Otherwise, if the numeric slug will never reasonably conflict with a year archive, undo WordPress\'s slug modification
$slug_num = intval( $original_slug );
if( REASONABLE_YEAR_ARCHIVE_LOWER > $slug_num || REASONABLE_YEAR_ARCHIVE_UPPER < $slug_num )
return $original_slug;
return $slug;
}
Note that I have not tested the above code and strongly discourage it\'s use. 很可能即使在应用预期的slug时,它仍然会被定向到基于日期的归档。
在应用Rewrite API.