为什么帖子永远不能有数字作为链接?

时间:2015-12-02 作者:NoBugs

今天我注意到了一件有趣的事情——无论你使用什么主题,都不可能给一篇文章命名一个数字,即使你给一篇文章命名了一个没有标签、帖子名称或类别名称冲突的长数字,你仍然可以将2015或1826628重命名为2015-2或1826628-2。

我想这不是一个bug,但我也不明白为什么你不能拥有mysite。com/20或类似于帖子的永久链接,当您将其命名为“20”,并且永久链接设置为postname时。

1 个回复
SO网友:bosco

为什么后缀会附加到(某些)数字贴子段塞中,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.

相关推荐

是否可以取消对特定帖子类型的POSTS_PER_PAGE限制?

我想知道我是否可以取消特定帖子类型的posts\\u per\\u页面限制。在存档中。php页面我显示不同的帖子类型,对于特定的“出版物”帖子类型,我想显示所有帖子。我如何在不影响传统“post”类型的情况下实现这一点?