使用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
相关产品推荐
相关产品推荐

