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

WordPress多站点新建站点时添加内容与CPT标签的时机问题

解决WordPress多站点新建站点时一次性添加CPT分类与帖子标签的问题

看起来你遇到的核心问题是执行时机不对加上重复触发,咱们一步步拆解解决:

问题根源分析

  1. wp_insert_site钩子太早:这个钩子是在站点数据库记录刚创建时触发,此时新站点的主题和插件还没完成初始化,你注册CPT和分类法的init钩子还没执行,自然找不到sldb_prtl_artikeltyp分类法,导致代码失效。
  2. 主题里的代码重复触发:主题的代码每次站点加载(前台访问、后台操作)都会跑一遍,没有判断是否已经执行过,所以每次CPT注册都会重复生成术语。

最优解决方案:精准控制执行时机+标记避免重复

我们需要做到三点:

  • 确保在新站点初始化完成后执行
  • 切换到新站点上下文操作
  • 用站点选项标记已执行,防止重复

下面是完整的代码实现,你可以把这段代码放在自定义插件里(推荐,比主题更灵活,不受主题切换影响):

function sldb_prtl_add_terms_on_site_creation( $blog_id ) {
    // 切换到刚创建的新站点上下文,确保操作针对这个站点
    switch_to_blog( $blog_id );

    // 检查站点是否已经执行过这个操作,避免重复触发
    if ( get_option( 'sldb_prtl_terms_added', false ) ) {
        restore_current_blog();
        return;
    }

    // 等到CPT和分类法注册完成后再执行(用init钩子,优先级设为100,比默认的10高)
    add_action( 'init', function() use ( $blog_id ) {
        // 创建"硬件"父术语
        $hardware_term = wp_insert_term( 'Hårdvara', 'sldb_prtl_artikeltyp' );
        if ( is_wp_error( $hardware_term ) ) {
            // 如果术语已存在,直接获取它的ID
            $hardware_term = get_term_by( 'name', 'Hårdvara', 'sldb_prtl_artikeltyp', ARRAY_A );
        }

        // 创建"鼠标"子术语
        $mouse_term = wp_insert_term( 'Möss', 'sldb_prtl_artikeltyp', array( 'parent' => $hardware_term['term_id'] ) );
        if ( is_wp_error( $mouse_term ) ) {
            $mouse_term = get_term_by( 'name', 'Möss', 'sldb_prtl_artikeltyp', ARRAY_A );
        }

        // 找到示例文章并给它打标签
        $example_post = get_page_by_title( 'Exempelartikel', ARRAY_A, 'sldb_prtl_artikel' );
        if ( $example_post ) {
            wp_set_post_terms( $example_post['ID'], $mouse_term['term_id'], 'sldb_prtl_artikeltyp' );
        }

        // 设置站点选项,标记操作已完成,以后不再执行
        update_option( 'sldb_prtl_terms_added', true );

        // 恢复到原来的站点上下文,避免影响其他操作
        restore_current_blog();
    }, 100 );
}
// 使用wp_initialize_site钩子(WordPress 5.1+),站点初始化完成后触发
add_action( 'wp_initialize_site', 'sldb_prtl_add_terms_on_site_creation' );

关键细节说明

  1. wp_initialize_site钩子:这是WordPress 5.1引入的钩子,比wp_insert_site晚触发,此时站点的基本结构已经搭建完成,主题和插件的初始化流程已经启动。如果你的WordPress版本低于5.1,可以用wpmu_new_blog替代,逻辑完全一致。
  2. 站点上下文切换:switch_to_blog和restore_current_blog确保我们的操作是针对刚创建的新站点,不会影响主站点或其他已存在的站点。
  3. 执行标记:通过sldb_prtl_terms_added这个站点选项,我们可以精确控制代码只执行一次,不管后续主题切换、插件更新还是CPT重新注册,都不会重复生成术语。
  4. init钩子优先级:把优先级设为100,确保你的CPT和分类法注册代码(通常用init优先级10)已经执行完毕,此时sldb_prtl_artikeltyp分类法已经存在,wp_insert_term就能正常工作。

额外注意事项

  • 确保你的CPT和分类法注册代码是在init钩子(优先级≤99)执行的,这样我们的代码执行时分类法已经存在。
  • 如果你的示例文章是通过插件创建的,要确保创建示例文章的代码在这段代码之前执行,或者在代码里添加判断,如果示例文章不存在就先创建它。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:33:09