WPML Version: 3.2.7


The action hook makes it possible to set or update an element’s language information. Apart from its straightforward implied usage, the hook can prove to be useful when one needs to connect two elements with one as the “Translation of” the other. Refer to the “Hook Example Usage” section below for an example of this.

Inserting Content
do_action( 'wpml_set_element_language_details', array $args )
(array) (Required) An array of arguments to be used.

  • element_id(bool) Use term_taxonomy_id for taxonomies, post_id for posts
  • element_type(string) The type of an element. Can be a post type: post_post, post_page, post_attachment, post_nav_menu_item, post_{custom post key} or taxonomy: tax_category, tax_post_tag, tax_nav_menu, tax_{custom taxonomy key}. Defaults to post_post if not set.
  • trid(int) The trid to which the element is to be assigned to. If set to FALSE it will create a new trid for the element causing any potential translation relations to/from it to disappear.
  • language_code(string) The language code for the element
  • source_language_code(string) The source language code for the element. NULL is reserved for original elements i.e. elements that are not a translation of another. Defaults to NULL when not set.
  • check_duplicates(bool) Defaults to TRUE. What this does is, it checks whether another element of a different type with the same ID already exists and outputs a user-level notice (E_USER_NOTICE) with the message “Element ID already exists with a different type”
hook example usage:
In the example below, we use the my_insert_posts() function to insert two posts from the front-end. One original and one translation.
This function is called in element_connect_on_insert(). This is our main function which will connect the two posts together.Note the use of two other useful WPML hooks inside. The wpml_element_type filter for filtering the element type to a value WPML will understand and the wpml_element_language_details filter for retrieving the original trid and language code.All of this hooks on wp_footer so our filters and actions will fire when the footer is loaded on the front-end.


add_action('wp_footer', 'element_connect_on_insert');

function my_insert_posts() {
	$output = array();

	// Create original post object
	$my_original_post = array(
		'post_title'    => 'My original post',
		'post_content'  => 'This is my original post.',
		'post_status'   => 'publish',
		'post_author'   => 1,
		'post_category' => array(1)

	// Create translation post object
	$my_translated_post = array(
		'post_title'    => 'My translated post',
		'post_content'  => 'This is my translated post.',
		'post_status'   => 'publish',
		'post_author'   => 1,
		'post_category' => array(2) // NOTE: this is the translated category id!

	// Insert the 2 posts into the database
	$original_post_id = wp_insert_post( $my_original_post );
	$translated_post_id = wp_insert_post( $my_translated_post );

	return $output = array(
		'original' => $original_post_id,
		'translation' => $translated_post_id

function element_connect_on_insert() {
	$inserted_post_ids = my_insert_posts();

	if ( $inserted_post_ids) {
		// https://wpml.org/wpml-hook/wpml_element_type/
		$wpml_element_type = apply_filters( 'wpml_element_type', 'post' );
		// get the language info of the original post
		// https://wpml.org/wpml-hook/wpml_element_language_details/
		$get_language_args = array('element_id' => $inserted_post_ids['original'], 'element_type' => 'post' );
		$original_post_language_info = apply_filters( 'wpml_element_language_details', null, $get_language_args );
		$set_language_args = array(
			'element_id'    => $inserted_post_ids['translation'],
			'element_type'  => $wpml_element_type,
			'trid'   => $original_post_language_info->trid,
			'language_code'   => 'de',
			'source_language_code' => $original_post_language_info->language_code

		do_action( 'wpml_set_element_language_details', $set_language_args );