解决方案可能有点棘手,但您走的是正确的道路。
您需要使用动态重写注册分类法和post类型:
function wpse346452_cpt() {
register_taxonomy( \'campaign\', \'asset\', array( \'label\' => \'Campaing\' ) );
register_post_type( \'asset\', array(
\'public\' => true,
\'label\' => \'Asset\',
\'rewrite\' => array(
\'slug\' => \'%campaign_name%\',
),
) );
}
add_action( \'init\', \'wpse346452_cpt\' );
您需要替换该动态重写,以便它表示所附的术语:
function wpse346452_permalink( $post_link, $post ) {
if( is_object( $post ) && $post->post_type == \'asset\' ) {
$terms = wp_get_object_terms( $post->ID, \'campaign\' );
if( $terms ) {
return str_replace( \'%campaign_name%\' , $terms[0]->slug , $post_link );
}
}
return $post_link;
}
add_filter( \'post_type_link\', \'wpse346452_permalink\', 10, 2 );
因为重写规则尚未定义,所以现在得到404。每次你在竞选活动中有一个新的任期,你都需要一个新的规则。因此,让我们为每个可用术语动态添加重写规则:
function wpse346452_dynamic_rw_rules() {
$terms = get_terms( array(
\'taxonomy\' => \'campaign\',
\'hide_empty\' => false,
) );
if( !empty( $terms ) ) {
foreach( $terms as $term ) {
add_rewrite_rule(
\'^\' . $term->slug . \'/(.*)/?$\',
\'index.php?post_type=asset&name=$matches[1]\',
\'top\'
);
}
}
}
add_action( \'init\', \'wpse346452_dynamic_rw_rules\' );
现在它将根据您的需要工作。但缺点是,无论何时添加新活动,都需要转到永久链接设置并保存,从而刷新重写规则。因此,让我们也将其自动化:
function wpse346452_flush_rewrite( $term_id, $tt_id, $taxonomy = \'campaign\' ) {
if( $taxonomy === \'campaign\' ) {
$term = get_term_by( \'term_taxonomy_id\', $tt_id );
add_rewrite_rule(
\'^\' . $term->slug . \'/(.*)/?$\',
\'index.php?post_type=asset&name=$matches[1]\',
\'top\'
);
if( !function_exists( \'flush_rewrite_rules\' ) ) {
require_once WPINC . \'/rewrite.php\';
}
flush_rewrite_rules();
}
}
add_action( \'edit_term\', \'wpse346452_flush_rewrite\', 10, 3 );
add_action( \'create_campaign\', \'wpse346452_flush_rewrite\', 10, 3 );
在这里,我们将连接到创建和编辑术语,如果分类法是活动,那么我们将启动
flush_rewrite_rules()
刷新永久链接。
据我所知,这是做这件事的唯一完美方法。但这样做是有限制的。由于添加术语没有限制,因此它可能与其他插件的重写规则冲突。所以需要小心使用。