WPML and Polylang
5 min read
When a post has translations (in WPML or Polylang) each translation is a separate post with its own row of field values. The multilingual integration decides, per field, how those rows relate. A product's SKU should be the same in every language; its description should be translated; an internal note should not follow the translation at all.
Plan | Business and Agency (feature |
Needs | WPML or Polylang active. Without one of them the setting is hidden and every field behaves like Translate. |
Applies to | Posts (any post type that has translations). Users, terms, comments and options are not covered. |
The setting: "In translations"
Open a field in the builder, Display tab. The select In translations (hint: What a WPML or Polylang translation of the post gets for this field.) has three modes:
Mode | Label in the builder | Meaning |
|---|---|---|
| Translate (start from the original) | The translation has its own value. It is prefilled from the original when you start a translation, then edited freely. |
| Copy (always the original value) | The translation always holds the original's value. Whenever either post is saved, the translation is overwritten by the original. |
| Ignore (start empty) | The translation starts empty. It is never copied or synced. |
In a definition (export file or PHP registration) the mode is the field's translation value; translate is the default and is left out of exports:
[ 'key' => 'sku', 'label' => 'SKU', 'type' => 'text', 'translation' => 'copy' ],
[ 'key' => 'title', 'label' => 'Title', 'type' => 'text' ], // translate
[ 'key' => 'note', 'label' => 'Note', 'type' => 'text', 'translation' => 'ignore' ],The mode of a top-level field covers everything the field stores, including a repeater's rows, a link's parts and the other columns that belong to it (the same columns a duplicate would copy). Sub-fields follow their container.
What is the "original"?
Plugin | Original | Translations |
|---|---|---|
WPML | The post WPML flags as the original (source language) of the translation group | The other posts of the group |
Polylang | The post in Polylang's default language | The other languages' posts |
With Polylang, a group of translations without a post in the default language has no original: nothing is copied or synced between those posts (verified with posts in de and fr only).
What happens when
You start a new translation
The edit screen of the new post shows values before it is saved:
- WPML: the add-translation link carries
tridand the post type; Polylang:from_post. - The fields of Translate and Copy mode are prefilled from the original; Ignore fields are empty.
- Nothing is stored until the translator saves the post. The prefill applies only while the translation has no stored row for that group; afterwards the saved values are shown.
Opening the original itself shows nothing special.
You save a translation
After the edit screen stored its values, the Copy fields are overwritten with the original's current values. Translate and Ignore fields keep what the translator typed. A translator can type into a Copy field, but the value is replaced on save (the field is not made read-only).
You save the original
Every Copy field of all its translations is updated to the original's values; a translation that has no row yet gets one with those columns. Translate and Ignore fields of translations are untouched. Clearing a Copy field in the original (when the original has a row) clears it in the translations.
If the original has no row at all, nothing is copied and the translations keep their own values (verified).
You duplicate (WPML only)
When WPML makes a duplicate of a post into another language (icl_make_duplicate), the duplicate gets the values of every field in Translate and Copy mode. Ignore fields stay empty. Polylang has no corresponding hook, so there only the prefill on a new translation applies.
You change a field's mode later
Nothing is rewritten at once. A field switched to Copy is synchronised the next time the original or a translation is saved.
Example: product catalogue in three languages
- Fields:
sku(Copy),price(Copy),tagline(Translate),internal_note(Ignore). - Create the English product with SKU
A-100, price 19.50 and a tagline. - Click the + for German in WPML or Polylang. The German edit screen opens with SKU, price and tagline prefilled (the tagline in English, to be translated) and an empty note.
- Translate the tagline, save. The SKU and price stay
A-100and19.5whatever the translator typed. - Later you change the price in English and update. The price of every translation follows.
Verified how
Neither WPML nor Polylang is installed on the documentation site. The behaviour was tested with the public APIs they offer stubbed the same way the plugin reads them: WPML's wpml_element_trid and wpml_get_element_translations filters and icl_make_duplicate; Polylang's pll_get_post_translations() and pll_default_language(). The Business plan was tested with the simulated plans: on Pro and on an expired license the prefill, the sync and the duplicate did nothing and the setting was hidden. The real translation screens of both plugins (including WPML's own custom-field synchronisation settings) were not exercised.
Limitations
- Only posts. Terms, users and options with translations are not handled.
- A field can be exactly one of three modes. There is no per-language setting and no list of languages to exclude.
- The integration reads values from the stored row; it does not translate text. Machine translation is not part of it.
- It does not remove WPML's or Polylang's own custom-field synchronisation: if you also configure a custom field of the same name in WPML's Custom Field Translation, WPML copies post meta, which is separate from the plugin's tables. For fields in the group tables, use the In translations setting.
- The page title, content and other core fields are managed by WPML or Polylang.
- Programmatic SEO (Pro) has its own language handling for generated pages; see Multilingual pages.
Troubleshooting
Problem | Check |
|---|---|
No In translations select in the builder | The plan is Business or Agency, WPML or Polylang is active, and the field is edited in the Display tab. |
The translation is not prefilled | It already has a stored row for that group (it was saved before), the post has no original, or the new-translation link does not carry |
A Copy field keeps jumping back | By design: it is overwritten on every save by the original's value. Edit the original, or switch the field to Translate. |
Polylang: nothing is copied | No post in the default language exists in that translation group. |
Values differ after switching a field to Copy | Save the original once; translations are synchronised on save. |
Still stuck? Contact support