PhpRiot
News Archive
PhpRiot Newsletter
Your Email Address:

More information

WPML: icl_object_id() and custom post types

Note: This article was originally published at Planet PHP on 29 October 2011.
Planet PHP

Digressing from my usual grounds, I moonlighted a bit on a Wordpress project in September. One of the project's goals was to make the entire website bi-lingual: French and German (or the way around?). And once multi-lingual is an object, WPML is the plugin to use (as far as Wordpress is concerned).

WMPL in a nutshell

WPML is a commercial plugin - and as far as I am concerned: it's money well spend.

In case there's not a lot customization going, WPML works out of the box. For those digging a little deeper, WPML includes all these extra features and functions which are supposed to make life easier, but in reality, it doesn't always work out that way.

One example is rewriting queries to only show posts in the currently selected language. It only seems to work so far, or every once in a while. WPML's documentation is out-dated (or sometimes wrong), their forum is semi-useful (hint: you have to login to see anything useful) and so on. These last issues are especially sour for a commercial product.

icl_object_id()

One of the core features to make your theme work is the icl_object_id() function. It's supposed to take an ID (and a type) as an argument and should return the ID of the translation in the currently selected language. But add custom post types (a pretty useful plugin: custom post types UI) and it gets a little confusing.

It took me a while to find my way around it, so here's a small snippet to make icl_object_id() work with any post type.

Use case

There's an image.php in my theme (which is based on TwentyEleven), but we don't want a page dedicated to a single image.

Telling contributors of the website not to link to it only goes that far: the solution is to redirect the user to the article. Now add custom post types and a multi-lingual experience: Problem?

Not so much!

This is what we started off with:

post_parent));

Hint, hint: Ugh... an extra SQL-query to get the permalink.

The above works if you don't use WPML. ;-)

Then we advanced to this:

post_parent; // this is the parent the image belongs to if (defined('ICL_LANGUAGE_CODE')) { // this is to not break code in case WPML is turned off, etc. $_type = get_post_type($parent); $parent = icl_object_id($parent, $_type, true, ICL_LANGUAGE_CODE); } wp_redirect(get_permalink($parent));

Hint, hint: Add one query for the post type, and who knows how many more in icl_object_id(). Finish off with the one for the permalink.

Step by step!

  1. $parent is what the current post is associated with. E.g. this is an image, attached to a certain post. The post is its parent.
  2. Then I get the post type ($_type) - if you don't run custom post types, this is likely post. But it could be anything.
  3. icl_object_id() takes four arguments:
    • $parent: the current id
    • $_type: the type of object (e.g. post, category, post_tag, a or your custom post type)
    • true: failover to return the original if nothing was found
    • ICL_LANGUAGE_CODE: this is a constant introduce by WPML, it contains the current language (de, en, fr, ...)

Fin

That's all!