How to Programmatically Add Multi Language Post in WordPress and WPML


I recently need to create wordpress post programmatically. It is so easy with wp_insert_post. However, the twist is how to add it using WPML for multi language support. WPML is nice plugin, but I didn’t find straight forward answer to it. Than I found a nice article from Ionuț Staicu, that does what I need. And it is the most popular article I found and seems like only solution people have. Article can be read in http://www.iamntz.com/3424/frontend-developer/programmatically-insert-posts-in-wordpress-and-set-language-for-wpml-plugin/. Though it doesn’t seems to solve my problem.

I email Ionuț Staicu, and to my surprise the nice guy email me back in couple of hour, and give me few suggestion and even his code snippet. I really love reading his code. On trying that code I found that he copy WPML API wpml_add_translateable_content function in his code and comment out the Check for duplicate addition of same content.

Doing so make my code work, but I was not satisfied. Sorry Ionuț Staicu, that doesn’t make me happy. Reason was simple. A company running such plugin cannot make such silly mistake. I trust WPML developer, they are of course better than me to realise what they are putting as check. 

So, what is wrong in my code? Well the answer was simple. WPML hook wp_insert_post to run “add_translate”. So, you don’t have to call it. However to add multiple language you need to call “wp_insert_post” for all language you want to add the code. This is easy..huh? no it is not easy. WPML call add_translate, but didn’t link them. I am not sure if they have any “insert” meta field that does the link. But there is no clearer way I found. So, I go back to add_translateable function and found that they have nothing but only

$sitepress->set_element_language_details(...);

other than checks. So, what does this function do. Simple, it change/add the Translation into database. So, all I have to do is, I need to update the Secondary language with the transalation id [3rd parameter of set_element_language_details ] to my default translation ID. Sound complex, no worries just read code below:

$_POST['icl_post_language'] = $language_code = 'he';  //Setting hebrew post. Ionuț Staicu suggest to have $_POST set. I follow him
$newPostID = wp_insert_post( $PostDATA );	//See wp_insert_post for details		

$trigid = wpml_get_content_trid('post_property', $newPostID); // Find Transalation ID function from WPML API. 

$_POST['icl_post_language'] = $language_code = 'fr'; // Set another language
$tpropertyid1 = wp_insert_post( $PostDATA ); // Insert French post
$sitepress->set_element_language_details($tpropertyid1, 'post_property', $trigid, $language_code); // Change this post translation ID to Hebrew's post id

//Repeating for English post.
$_POST['icl_post_language'] = $language_code = 'en'; 
$tpropertyid2 = wp_insert_post( $PostDATA );
$sitepress->set_element_language_details($tpropertyid2, 'post_property', $trigid, $language_code);

So, that just insert and link all languages you want. I did this in PHP CLI command line, and it works like charm. Hope this help someone. 

 

 

, ,

7 responses to “How to Programmatically Add Multi Language Post in WordPress and WPML”

  1. Thank you for this article and sharing your solution, it helped me a lot.

    wpml_get_content_trid was raising an error for me because I was using “post_properties”. Having a look to wp3_icl_translations table in wordpress dbb, I realize that you should use “post_post” for post content type.

  2. I got an error using $trigid = wpml_get_content_trid(‘post_page’, $adden);
    Error: Call to undefined function wpml_get_content_trid()

    So I went straight to:

    $trigid = $sitepress->get_element_trid($adden, ‘post_page’);

    That works !
    Also important to remember to call global $sitepress;

  3. Hi, my solution is not very elegant but it seems to work.
    NOTE: “poi” is my custom post type.

    global $sitepress;
    $defaultLanguage = $sitepress->get_default_language();

    $pid = wp_insert_post( array(
    ‘post_title’ => ‘the post title!’,
    ‘post_status’ => ‘publish’,
    ‘post_type’ => ‘poi’,
    ));

    if ($lang != $defaultLanguage){
    $trid = $sitepress->get_element_trid($pid, “post_poi”);
    $sitepress->set_element_language_details($pid, “post_poi”, $trid, $lang);
    }
    else {
    // no action to do: post is already in right language
    }

  4. Here is another way is duplicate post and update post data

    //in $postarray is original english post data

    $post_id = wp_insert_post($postarray);
    $langs_to_duplicate=[‘es’,’ru’];
    foreach ($langs_to_duplicate as $lang) {
    $tr_post_id = $sitepress->make_duplicate( $post_id, $lang );
    echo ‘Duplicated post ID: ‘.$tr_post_id.’ for Lang is: ‘.$lang.”;
    $postarray = get_post_data_by_lang($lang);
    $postarray[‘ID’] = $tr_post_id;
    $postarray[‘post_author’] = 1;
    if (wp_update_post($postarray, true)){
    echo ‘Updated post ID: ‘.$tr_post_id.’ Lang is: ‘.$lang.”;
    }
    }

  5. Useful if you use duplicate:

    //delete duplicate relation to prevent lose changes in secondary langs if english was changed
    $wpdb->query(“delete from wp_postmeta where meta_key = ‘_icl_lang_duplicate_of’;”);