首先我来解释一下问题。
当我创建具有相似名称的类别时,会发生以下情况:
https://www.example.com/cars/ford/parts
https://www.example.com/cars/toyota/parts1
为什么会这样?父母不同,那么为什么 WordPress 会处于 1 到第二部分类别?
有解决方法吗?
我看到很多人都有同样的问题。如果有一种方法可以让他们在父母的鼻涕虫不同时拥有相同的鼻涕虫,那就太好了。
我从未经历过足够的痛苦来弄清楚为什么会发生这种情况,但我可以确认它确实发生了。我只需要处理清理工作,但没有人愿意添加其他类别,因此我的懒惰在简单修复后阻止了我。
我所做的是直接处理 WP 的表(wp_terms 和 wp_term_taxonomy),在使用第二个(重复)术语创建的 wp_term_taxonomy-item 上设置正确的 term_id,从而获得不同的 slug。这是一个直接、相当无害的操作,因为它不会更改 term_taxonomy_id,因此根本不关心 wp_term_relationships。
像往常一样,直接操作数据时,首先在开发安装上进行。
我在需要永久链接相关定制的地方使用了插件。它的工作方式就像魅力。我希望这会有所帮助。
WordPress 不允许您在同一分类中存在重复的术语,它们在数据库中必须是唯一的。但是,我们可以扩展 WordPress 核心以使 url 结构正常工作,同时保留独特的术语 slugs。
使用您的示例:
cars/ford/parts
和cars/toyota/parts
网址,其中ford_parts
和toyota_parts
是cars
分类中的独特子术语,它们的父术语分别是ford
和toyota
。
首先,重写规则:
/**
* Add custom rewrite rules for parent/child term urls.
*
* Adds a rewrite rule that will match terms
* that have their slug prefixed with the parent term
* slug, separated by an underscore, but their url
* is just the child term slug.
*/
function prefix_custom_hierarchical_taxonomy_rewrite_rules() {
$tax_object = get_taxonomy( 'cars' );
if ( $tax_object ) {
$tax_slug = $tax_object->rewrite['slug'];
add_rewrite_rule(
$tax_object->rewrite['slug'] . '/([^/]+)/([^/]+)/?',
'index.php?' . $tax_object->query_var . '=$matches[1]_$matches[2]',
'top'
);
}
}
add_action( 'init', 'prefix_custom_hierarchical_taxonomy_rewrite_rules', 100 );
然后过滤
term_link
,以便删除子术语链接中的 slug 的“parent_”部分:
/**
* Filter the term link to handle hierarchical taxonomy permalinks.
*
* This will filter the term link to remove the parent term slug
* from the child term url, so that the url is just the child term slug,
* where the child term name is "parent_child" and the parent term name is "parent".
*
* @param string $link The term link
* @param WP_Term $term The term object
* @param string $taxonomy The taxonomy name
* @return string
*/
function prefix_custom_term_link( $link, $term, $taxonomy ) {
if ( $taxonomy !== 'cars' ) {
return $link;
}
// Get the parent term
$parent_term = get_term( $term->parent, $taxonomy );
if ( $parent_term && ! is_wp_error( $parent_term ) ) {
// Remove the "parent_" prefix from the child term slug
// to generate a url that looks like /parent/child/
$link = str_replace( '/' . $term->slug, '/' . str_replace ( $parent_term->slug . '_', '', $term->slug ), $link );
}
return $link;
}
add_filter( 'term_link', 'prefix_custom_term_link', 10, 3 );
您可能还想过滤
parse_query
以检查是否有任何不遵循此结构的子术语。这避免了必须将 all 您的子类别 slug 设置为 parent_child
模式,您可以将其应用于那些具有“重复”url slug 的类别。
注意: 下一个示例正在查找
category_name
查询变量,该变量由 category
分类法使用。对于可能会有所不同的自定义分类法 - 请参阅 register_taxonomy
/**
* Parse the query to handle hierarchical taxonomy permalinks.
*
* This filter the query to check for terms that are child terms
* yet do not have the parent term in the slug, thus the parent/child
* structure should literally look for a "child" slug, not "parent_child"
*
* @param WP_Query $query The WP_Query instance (passed by reference)
* @return void
*/
function prefix_custom_parse_query($query) {
if ( isset( $query->query_vars['category_name'] ) ) {
$slug = $query->query_vars['category_name'];
if ( strpos( $slug, '_' ) !== false ) {
list( $parent, $child ) = explode( '_', $slug, 2 );
if ( ! term_exists( $slug, 'category' ) && term_exists( $child, 'category' ) ) {
$query->query_vars['category_name'] = $child;
}
}
}
}
add_action( 'parse_query', 'prefix_custom_parse_query' );
我已将其纳入要点此处,但使用
category
分类法而不是自定义cars
分类法。
备注:
prefix_
命名更新为您的主题或插件独有的名称。{parent-slug}_{child-slug}
的模式。您可以将其更改为另一个分隔字符,但请小心使用破折号 -
,因为这是生成名称时核心使用的默认值(空格变为破折号)。/%postname%/
在“设置”>“永久链接”中设置。