Originally written
December 8, 2011
May 21, 2015

WPML’s Translation Editor can translate the standard post fields and any custom field that you choose. However, sometimes, you need to translate content that WPML simply cannot understand.

For example, if you’re serializing data in custom fields, you don’t want translators to see the serialized code. You’d like to see the actual text for translation. WPML cannot tell that custom fields include data that required decoding. For that, we added filters that allow you to manipulate the content that goes to translation.

The order of things is:

  1. You send content for translation
  2. WPML collects the standard and custom fields and created translation packages.
  3. It applies the icl_data_for_pro_translation filter on those packages and sends to the Translation Editor.
  4. When translation completes, WPML sends the content through the icl_data_from_pro_translation filter.
  5. Then, WPML creates the translated post. It then calls the icl_pre_save_pro_translation filter and saves the post in the database.

You can use these filters to modify the translation packages, decode whatever fields you need and then encode them back when translation completes.

When you do that, remember that you’ll need to include the encoded fields in the content that goes to translation. If they’re not included, there’s nothing for your filters to process.

Decoding your custom fields before translation

Before content goes to translation, it passes through the icl_data_for_pro_translation filter. This is your opportunity to decode custom fields and turn them into text format.

If you have serialized data in a single custom field, you can de-serialize it, remove that field from the translation package and create new fields with the text content.

This is an example of how to use icl_data_for_pro_translation.

First, apply the filter:

$data = apply_filters('icl_data_for_pro_translation', $data);

The data you’ll receive looks like this:

$data = array(
  'contents' => array (
    'some_content' => array (
      'translate' => 1,
      'data' => %string%
      'format' => 'csv_base64'
    'some_content_ids' => array(
      'translate' => 0,
      'data' => '14,15',

Encoding back when translation completes

When translation completes, the content passes through the icl_data_from_pro_translation filter. Now, you should do the reverse operation of what you did in the icl_data_for_pro_translation filter. You should compile the text information in the fields that you created, remove those fields from the translation package and assemble the original field that WPML will save to the post meta.

Here is how to use the icl_data_from_pro_translation filter.

Call the filter in your code:

$translation = apply_filters('icl_data_from_pro_translation', $translation);

The $translation variable will contain fields like these:

[title] => Some document translated
[body] => <p>German:sa1212as</p>

[original_id] => 162
[tags] => Array
  [0] => A tag translated

[tag_ids] => 16
[some_content] => Array
  [0] => Some piece of content translated,
  [1] => Some other piece of content translated,

[some_content_ids] =>14,15

Filter them to create your serialized structures.

Final post processing

If you require any additional post processing, just before the Post is saved to the database, you can use the icl_pre_save_pro_translation filter.

$postarr = apply_filters('icl_pre_save_pro_translation', $postarr);

The $postarr structure contains the post details that go into the wp_posts table. It includes ID, post_title, post_content, etc., and is being passed to wp_insert_post.