WordPress自定义文章类型和自定义分类共用同一个根路径slug

在WordPress中如果注册一个自定义文章类型(Custom Post Type),并且为同时为这个类型注册一个自定义分类法(Custom Taxonomy),两者使用同一个根slug,访问这个类型的页面就会发生404报错。

这个slug具体指什么呢?举例说明:
https://www.my-site.com/product/123.html
https://www.my-site.com/product/term-name

以上URL分别作为product类型页面的详情页和分类列表页,URL中的product就是根slug。在使用register_post_type注册product文章类型的时候,代码体现为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
add_action('init', 'create_product_post_type', 0);
function create_product_post_type() {	
	register_post_type('product', array(
		'label' => 'Products',
		'public' => true,
		'show_ui' => true,
		'show_in_menu' => true,
		'capability_type' => 'post',
		'hierarchical' => false,
		'rewrite' => array('slug' => 'product'), //注意此行
		'supports' => array('title','editor','thumbnail'),
		'labels' => array (
			'name' => 'Products',
			'singular_name' => 'Product',
			'menu_name' => 'Products'
			)
		)
	);
}

注意第11行的rewrite参数,就为此自定义类型指定了根slug,即形成如下url:
https://www.my-site.com/product/123.html

再来注册自定义分类法,这里的分类法名称为product_category:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
add_action( 'init', 'create_product_taxonomies', 0 );
function create_product_taxonomies() {
	register_taxonomy(
		'product_category',
		'product',
		array(
			'labels' => array(
				'name' => 'Product Category'
			),
			'rewrite' => array('slug' => 'product'),//注意此行
			'show_ui' => true,
			'show_tagcloud' => false,
			'hierarchical' => true
		)
	);
}

注意第10行的rewrite参数,为此自定义分类指定了根slug,即形成如下url:
https://www.my-site.com/product/term-name
但实际上我们注册完毕后,前端页面会在自定义分类的URL产生404报错。

假如去掉第10行代码,默认的slug会变成product_category,即分类名称,这时候url会变成
https://www.my-site.com/product_category/term-name
这样虽然不会报错,但url比较难看,也不利于SEO。

要解决这个问题,需要在注册自定义类型的时候,修改参数如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
add_action('init', 'create_product_post_type', 0);
function create_product_post_type() {	
	register_post_type('product', array(
		'label' => 'Products',
		'public' => true,
		'show_ui' => true,
		'show_in_menu' => true,
		'capability_type' => 'post',
		'hierarchical' => false,
		'rewrite' => array('slug' => 'product/%product_category%'), //注意参数修改
		'has_archive' => 'product', //注意此行为添加的
		'supports' => array('title','editor','thumbnail'),
		'labels' => array (
			'name' => 'Products',
			'singular_name' => 'Product',
			'menu_name' => 'Products'
			)
		)
	);
}
 
add_action( 'init', 'create_product_taxonomies', 0 );
function create_product_taxonomies() {
	register_taxonomy(
		'product_category',
		'product',
		array(
			'labels' => array(
				'name' => 'Product Category'
			),
			'rewrite' => array('slug' => 'product'), //这里维持原样
			'show_ui' => true,
			'show_tagcloud' => false,
			'hierarchical' => true
		)
	);
}

最后,在post_type_link钩子上添加代码根据类型名称替换实际生成的url:

1
2
3
4
5
6
7
8
9
10
11
add_filter('post_type_link', 'custom_type_link', 1, 3);
function custom_type_link( $link, $post = 0 ){
	if ( false !== strpos( $link, '%product_category%' ) ) {
		$taxonomy_terms = get_the_terms( $post->ID, 'product_category' );
		foreach ( $taxonomy_terms as $term ) { 
			if ( ! $term->parent ) {
				$link = str_replace( '%product_category%', $term->slug, $link );
			}
		} 
	}
}

如此,两个url就能和平共处了。这个问题的修复逻辑是这样的:因在两处注册rewrite的时候使用同一个slug名,会造成rewrite冲突,产生404报错,那么我们就避免使用相同的slug,把第一处的slug改成’product/%product_category%’绕开这个问题。在实际生成url的时候再把类型名替换’%product_category%’字符串,从而解决问题。

本站所有文章均为原创,欢迎转载,请注明文章出处:https://blog.brain1981.com/2626.html。百度和各类采集站皆不可信,搜索请谨慎鉴别。技术类文章一般都有时效性,本人习惯不定期对自己的博文进行修正和更新,因此请访问出处以查看本文的最新版本。

关注我们的微信公众号-JennyStudio 本站记录了近几年的工作中遇到的一些技术问题和解决过程,“作品集”还收录了本人的大部分作品展示。除了本博客外,我们的工作室网站 – JennyStudio,内有更多作品回顾和展示。
您也可以扫描左边的二维码,关注我们的微信公众号,在微信上查看我们的案例。

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注