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

使用wp_insert_post插入的自定义帖子未在WordPress后台显示

解决WPML多站点模式下wp_insert_post插入自定义帖子未生成翻译的问题

嘿,我看到你在WPML多站点模式下,通过前端Ajax调用wp_insert_post插入自定义order类型帖子时,遇到了原始语言帖子成功插入但没自动生成翻译内容的问题——而且你已经排查过帖子类型注册的兼容配置却没解决,结合你提到的类似问题,我给你几个针对性的解决方案:

1. 确保Ajax请求传递正确的WPML语言上下文

WPML依赖语言参数识别当前请求的语言环境,但前端Ajax请求默认不会自动携带这些信息,这可能导致WPML无法触发翻译生成逻辑。你可以这么做:

  • 在Ajax请求的data参数里带上当前页面的语言标识,比如从html标签的lang属性获取,或者读取WPML的语言cookie:
jQuery.ajax({
    url: ajaxurl,
    type: 'POST',
    data: {
        action: 'create_order_post',
        // 传递WPML当前语言参数
        lang: jQuery('html').attr('lang'),
        // 你的帖子数据
        post_title: '测试订单',
        post_content: '订单详情内容'
    },
    success: function(res) {
        console.log('帖子创建成功:', res);
    }
});
  • 在后端Ajax处理函数中,通过WPML钩子手动设置语言环境,确保WPML能识别当前操作的语言:
function create_order_post_callback() {
    // 安全验证(必加)
    if (!check_ajax_referer('create_order_nonce', 'nonce', false)) {
        wp_send_json_error('权限验证失败');
    }
    
    // 设置WPML语言环境
    if (isset($_POST['lang'])) {
        do_action('wpml_switch_language', sanitize_text_field($_POST['lang']));
    }
    
    // 插入原始语言帖子
    $post_args = array(
        'post_type' => 'order',
        'post_title' => sanitize_text_field($_POST['post_title']),
        'post_content' => sanitize_textarea_field($_POST['post_content']),
        'post_status' => 'publish'
    );
    $original_post_id = wp_insert_post($post_args);
    
    if (is_wp_error($original_post_id)) {
        wp_send_json_error('帖子创建失败: ' . $original_post_id->get_error_message());
    }
    
    wp_send_json_success(array('post_id' => $original_post_id));
}
add_action('wp_ajax_create_order_post', 'create_order_post_callback');
add_action('wp_ajax_nopriv_create_order_post', 'create_order_post_callback');

2. 手动触发WPML翻译生成逻辑

自定义帖子类型默认不会自动触发WPML的翻译草稿生成,即使你在后台配置了可翻译,也需要手动调用WPML的钩子来创建翻译版本:

  • 在插入原始帖子后,遍历所有激活的语言,调用wpml_make_post_duplicate钩子生成对应语言的翻译草稿:
// 承接上面的Ajax处理函数,在获取$original_post_id后添加:
if ($original_post_id) {
    // 获取WPML默认语言和所有激活语言
    $default_lang = apply_filters('wpml_default_language', null);
    $active_langs = apply_filters('wpml_active_languages', null, array('skip_missing' => false));
    
    foreach ($active_langs as $lang) {
        if ($lang['code'] !== $default_lang) {
            // 为每个非默认语言创建翻译草稿
            do_action('wpml_make_post_duplicate', $original_post_id, $lang['code']);
        }
    }
}

3. 再次确认自定义帖子类型的WPML兼容配置

虽然你已经排查过,但再仔细核对这两处配置:

  • 注册order类型时,通过WPML过滤器明确标记为可翻译:
function register_order_post_type() {
    $args = array(
        'label' => '订单',
        'public' => true,
        'show_in_rest' => true,
        'supports' => array('title', 'content')
        // 其他常规参数
    );
    register_post_type('order', $args);
}
add_action('init', 'register_order_post_type');

// 告诉WPML这个帖子类型需要同步翻译
function wpml_setup_order_translatable($settings) {
    $settings['custom_posts_sync']['order'] = 'translate';
    return $settings;
}
add_filter('wpml_custom_posts_sync_options', 'wpml_setup_order_translatable');
  • 登录WPML后台,进入语言 → 设置 → 帖子类型翻译,确认order类型被设置为「可翻译」,并且翻译模式选择「创建翻译草稿」。

4. 排查多站点环境的权限与语言切换问题

如果是多站点模式,还要注意:

  • 确保Ajax请求没有跨站点的权限问题,当前站点的WPML语言配置是独立生效的;
  • 如果你的Ajax处理函数中用到了switch_to_blog,切换站点后要记得恢复,同时同步WPML的语言环境,避免语言上下文混乱。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:07:06