Language dependent IDs

Many themes display special posts, pages and categories specially, usually based on IDs. For example, a ‘Featured’ posts section in the home page, or highlighted categories.

In some cases, these IDs are hard-coded into the theme’s PHP and in others, the user selects them in the theme’s setting screen.

To display correctly, the theme needs to select the IDs per language. In WPML, IDs for posts, pages, categories and tags change when the language changes, so the theme needs to use the correct IDs of the active language.

WPML includes two options for achieving this.

You can either enable the automatic ID adjustment or use the icl_object_id manually in your theme.

Which Option to Use?

The automatic ID adjustment requires no changes in your code. You can use it with any theme and everything “just works”. The down-side for using it is slightly increased processing time and DB access, as WPML will hook to many functions and check that the output is correct for the active language.

Manual ID adjustment using the icl_object_id function will achieve the same results and can be more efficient in terms of processing. However, it requires significant coding in the theme.

If you’re building a theme from scratch, you should consider using icl_object_id to do it manually. If you’re starting with an existing theme, hacking and modifying the theme might not be realistic and the automated ID adjustment is probably the way to go.

In any case, by using any caching plugin, the performance impact of this operation are reduced to none. Caching is always recommended for sites of any size. WPML runs fine with WP Super Cache and W3 Total Cache (which we also use on different sites).

1) Automatically Adjust IDs

WPML can hook to WordPress API functions, detect when specific items are loaded and adjust IDs so that the results are adjusted for the active language.

This functionality is enabled by default and can be accessed via WPML->Languages (visible in Advanced mode):

Auto-adjust IDs

This will automatically adjust all IDs and can be used in any WordPress theme that uses the API correctly (almost any theme you can find).

2) Manually, using the icl_object_id function

Alternatively, if the automatic ID adjustment is off, you can use the icl_object_id function to achieve the same manually.

icl_object_id(ID, type, return_original_if_missing,language_code)

  • ID – the ID of the post, page, tag or category
  • type – ‘post’, ‘page’, ‘post_tag’, ‘category’ or ‘attachment’
  • return_original_if_missing – true if WPML should return the ID of the original language element if the translation is missing or false if WPML should return a NULL if translation is missing.
  • language_code (optional) – if set, forces the language of the returned object and can be different than the displayed language.

The ID argument can be the ID of the object in any language. What the function will do is look up the translation group for that object and then the ID of the corresponding object in the active language.

Example usage

icl_object_id(3, 'category', false)

Return the ID of the category that is the translation of category 3. If it’s missing, return NULL.

How to use in themes

If you’re writing a theme that needs to be used with WPML, but you also want it to run correctly without WPML, you should wrap these calls by function_exists() calls. For example, you can create this function in your functions.php file:

function lang_category_id($id){
  if(function_exists('icl_object_id')) {
    return icl_object_id($id,'category',true);
  } else {
    return $id;
  }
}

This function will return the ID of the translated category (if it exists) or the ID of the original category (if translation is missing). If WPML isn’t installed, the original category ID is always returned.

Translating arrays of IDs

Many times you need to convert an entire array of object IDs (most commonly category IDs). To do this, you can use the following function:

function lang_object_ids($ids_array, $type) {
 if(function_exists('icl_object_id')) {
  $res = array();
  foreach ($ids_array as $id) {
   $xlat = icl_object_id($id,$type,false);
   if(!is_null($xlat)) $res[] = $xlat;
  }
  return $res;
 } else {
  return $ids_array;
 }
}

This function also accepts the object type as an argument.

For example, to get an array of category IDs for categories 1,3 and 6 we’ll call:

lang_object_ids(array(1,3,6),'category')

Displaying page elements in different languages

The optional language_code argument allows mixing page elements in different languages.

For example, if you have an image gallery and don’t want to duplicate the images per language, follow this:

  1. Get the ID of the page in the language in which the gallery exists.
  2. Loop on the images for that page and display them.