You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WooCommerce复制产品时如何生成带自定义基址的产品slug

问题根因
  • 实现思路错误:WooCommerce产品URL中的基址部分(如你需要的/slug-base/)是注册product自定义文章类型时定义的重写规则,不属于单条产品的slug字段范畴。直接往单产品slug中写入带斜杠的路径,会被WordPress原生的slug清理函数自动过滤掉斜杠,无法形成路径分隔。你代码中用ASCII码47生成的/最终会被替换为空,写入的vendor/存库后会变成纯字符串vendor,和后续自动生成的产品名slug直接粘连,就出现了slug-baseproduct-name这种格式错误的链接。
  • 代码逻辑缺失:你当前的slug设置代码仅写入了前缀字符串,没有为复制生成的父产品生成合法的唯一slug,保存时WordPress会自动补全剩余内容,完全无法控制最终格式,还会在批量复制产品时产生严重的性能问题。
修复方案

1. 配置自定义产品URL基址

不要在单产品slug中硬编码前缀,直接通过WooCommerce提供的过滤器修改产品文章类型的重写基址,全局统一生成符合要求的链接格式:

add_filter( 'woocommerce_register_post_type_product', function( $args ) {
    // 此处修改为你需要的自定义基址,最终链接结构为:域名/自定义基址/产品名
    $args['rewrite']['slug'] = 'slug-base';
    return $args;
} );

代码添加完成后,进入WordPress后台「设置-固定链接」页面,直接点击「保存更改」(无需修改原有配置),刷新系统重写规则即可生效,避免出现404错误。

2. 修正产品复制方法的slug逻辑

移除原有错误的硬编码前缀slug代码,调用类自带的generate_unique_slug方法为复制生成的父产品、子变体统一生成合法的唯一slug,基址会自动通过前面配置的重写规则拼接,不需要手动写入。修正后的完整方法代码如下:

/**
 * Function to create the duplicate of the product.
 *
 * @param WC_Product $product The product to duplicate.
 * @return WC_Product The duplicate.
 */
public function product_duplicate( $product ) {
    /**
     * Filter to allow us to exclude meta keys from product duplication..
     *
     * @param array $exclude_meta The keys to exclude from the duplicate.
     * @param array $existing_meta_keys The meta keys that the product already has.
     * @since 2.6
     */
    $meta_to_exclude = array_filter(
        apply_filters(
            'woocommerce_duplicate_product_exclude_meta',
            array(),
            array_map(
                function ( $datum ) {
                    return $datum->key;
                },
                $product->get_meta_data()
            )
        )
    );

    $duplicate = clone $product;
    $duplicate->set_id( 0 );
    /* translators: %s contains the name of the original product. */
    $duplicate->set_name( sprintf( '%s', $duplicate->get_name()) );
    $duplicate->set_total_sales( 0 );
    if ( '' !== $product->get_sku( 'edit' ) ) {
        $duplicate->set_sku( wc_product_generate_unique_sku( 0, $product->get_sku( 'edit' ) ) );
    }
    $duplicate->set_status( 'draft' );
    $duplicate->set_date_created( null );
    // 移除原错误的硬编码前缀逻辑,生成唯一合法slug
    $this->generate_unique_slug( $duplicate );
    $duplicate->set_rating_counts( 0 );
    $duplicate->set_average_rating( 0 );
    $duplicate->set_review_count( 0 );
    $duplicate->add_meta_data( '_is_clone', 'true' );

    foreach ( $meta_to_exclude as $meta_key ) {
        $duplicate->delete_meta_data( $meta_key );
    }

    /**
     * This action can be used to modify the object further before it is created - it will be passed by reference.
     *
     * @since 3.0
     */
    do_action( 'woocommerce_product_duplicate_before_save', $duplicate, $product );

    // Save parent product.
    $duplicate->save();

    // Duplicate children of a variable product.
    if ( ! apply_filters( 'woocommerce_duplicate_product_exclude_children', false, $product ) && $product->is_type( 'variable' ) ) {
        foreach ( $product->get_children() as $child_id ) {
            $child           = wc_get_product( $child_id );
            $child_duplicate = clone $child;
            $child_duplicate->set_parent_id( $duplicate->get_id() );
            $child_duplicate->set_id( 0 );
            $child_duplicate->set_date_created( null );

            // 预生成唯一slug,避免批量复制时逐次查询可用slug导致的性能下降
            $this->generate_unique_slug( $child_duplicate );

            if ( '' !== $child->get_sku( 'edit' ) ) {
                $child_duplicate->set_sku( wc_product_generate_unique_sku( 0, $child->get_sku( 'edit' ) ) );
            }

            foreach ( $meta_to_exclude as $meta_key ) {
                $child_duplicate->delete_meta_data( $meta_key );
            }

            /**
             * This action can be used to modify the object further before it is created - it will be passed by reference.
             *
             * @since 3.0
             */
            do_action( 'woocommerce_product_duplicate_before_save', $child_duplicate, $child );

            $child_duplicate->save();
        }

        // 读取保存后的完整产品对象,关联新生成的子变体
        $duplicate = wc_get_product( $duplicate->get_id() );
    }

    return $duplicate;
}
补充说明

如果你不需要全局替换所有产品的URL基址,仅想给复制生成的产品添加专属URL前缀,不要通过修改单产品slug的方式实现,需要单独注册自定义重写规则匹配对应路径,否则依然会出现斜杠被过滤、链接格式错误的问题。

内容的提问来源于stack exchange,提问作者Flavio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 07:45:30