Some things work differently on a multilingual site by design: a WordPress function keyed on a default-language term, a date suffix WordPress cannot localize, a slug the Advanced Translation Editor does not invent. Support questions raise them as bugs; they are not. This page says what happens, why, and what to do instead.
has_category() and other conditional tags on translated posts
WordPress core's has_category() is not filtered by WPML, on purpose. On a translation the category is the translated term, which has its own slug, so has_category('news') is false on the French post even though the French post is in the French "news" category. The same holds for has_term(), in_category() and any code that compares a default-language slug or term id. Call the conditional with the translated slug, or resolve the term id through the wpml_object_id filter first.
What you see
The native WordPress function has_category does not work for translated posts.
An example of this is as follows:
- We have a category with the English slug “test” and its French translation “test-fr”.
- This category is assigned to posts.
- When you invoke the
has_category("test")inside a loop in your theme’s single.php file, it returns true for the default language but false for the translation.
What to do
Define a new filter in your theme’s functions.php file:
function wp_has_category ($category) {
$category = get_term_by('name', $category, 'category');
return has_category($category);
}
add_filter('wp_has_category', 'wp_has_category', 10, 1);Replace the has_category function with this new filter:
apply_filters( 'wp_has_category', 'test' )
This filter takes the translated category based on the name of original one and checks if the translated category is assigned to a post.
Reference: wpmlcore-3024.
Date suffixes (1st, 2nd, 3rd) are not translatable
This is a limitation of WordPress core, not of WPML: the suffix comes from PHP's date formatting and never passes through a translation function.
What you see
Some themes or plugins use the wp_date() or date_i18n() WordPress functions to display dates. These dates may use a suffix as 1st or 26th, depending on the parameters selected.
Currently, it’s not possible to translate date suffixes because of a longstanding known limitation in WordPress core (opens in a new tab).
What to do
As a workaround, you can use the wp_date filter to get the date, then modify the suffix before it’s rendered on the page. Please make a full backup of your site before proceeding and follow the steps below:
- Add a small
wp_datefilter to your theme's functions.php that registers each suffix as a string (icl_register_string) and returns its translation (icl_t) in place of the English suffix: - Open the page where the dates are displayed. This will execute the filter added.
- Go to WPML → String Translation and translate the dates.
- You will need to translate each suffix separately (e.g. 1st, 2nd…) because it may change depending on the language.
Reference: compsupp-5773.
The Advanced Translation Editor does not invent a slug
The editor translates the slug field when you fill it and keeps the original slug when you leave it empty. It never derives a slug from the translated title on its own.
What you see
If you translate a post using our Advanced Translation Editor, the slug field is not filled automatically. If you then decided to leave the slug field empty, it loads the original language slug in the translated post.
Reference: wpmlsupp-8574.
Page-builder shortcodes in a WooCommerce product short description
The short description is the post excerpt, a plain-text field by WordPress's definition, so WPML does not parse page-builder shortcodes in it the way it does in the content. WooCommerce happens to render them, which is why the mismatch surprises people.
What you see
The WooCommerce product short description is based on the post excerpt field, and that is ordinarily a simple text field that does not handle shortcodes. As such it is not expected that if you paste page-builder shortcodes into the post excerpt they would work, and when translating post excerpts WPML does not attempt to handle such shortcodes.
But WC handles these “excerpts” a little differently, and shortcodes do work, but WPML still acts as if they do not, and if the shortcode includes attributes that need translating or internal links that should be handled automatically that is not readily possible.
What to do
We have prepared code that can be added as a plugin to provide this functionality. Copy and paste the below code into a file that you might name wpmlpb-excerpts.php and save in your wp-content/plugins/ directory, then activate the plugin.
<?php
/**
* Plugin Name: WPML Page Builders - Proces Excerpts
* Description: Parses shortcode strings in exceprts.
* Version: 1.0
*/
namespace WPMLPB686;
( new Excerpts() )->add_hooks();
class Excerpts {
const SEPARATOR_START = '<!--WPML_EXCERPT_START-->';
const SEPARATOR_END = '<!--WPML_EXCERPT_END-->';
public function add_hooks() {
add_filter( 'wpml_pb_shortcode_content_for_translation', [ $this, 'joinWithContent' ], 10, 2 );
add_filter( 'wpml_tm_translation_job_data', [ $this, 'excludeFromJob' ], 10, 2 );
add_action( 'wpml_pro_translation_completed', [ $this, 'splitFromContent' ], 999 );
}
public function joinWithContent( $content, $id ) {
$post = get_post( $id );
if ( $post && $post->post_excerpt ) {
$content .= self::SEPARATOR_START . $post->post_excerpt . self::SEPARATOR_END;
}
return $content;
}
public function excludeFromJob( $package, $post ) {
if ( preg_match( '/[[^]]+]/', $post->post_excerpt ) ) {
$package['contents']['excerpt']['translate'] = 0;
$package['contents']['excerpt']['data'] = '';
}
return $package;
}
public function splitFromContent( $post_id ) {
$post = get_post( $post_id );
if ( $post && false !== strpos( $post->post_content, self::SEPARATOR_START ) ) {
$start_pos = strpos( $post->post_content, self::SEPARATOR_START );
$end_pos = strpos( $post->post_content, self::SEPARATOR_END, $start_pos );
if ( false !== $end_pos ) {
$content = substr( $post->post_content, 0, $start_pos );
$excerpt = substr( $post->post_content, $start_pos + strlen( self::SEPARATOR_START ), $end_pos - $start_pos - strlen( self::SEPARATOR_START ) );
if ( $excerpt ) {
wp_update_post(
[
'ID' => $post_id,
'post_content' => $content,
'post_excerpt' => $excerpt,
]
);
}
}
}
}
}
Reference: wpmlpb-686.
Different domains per language on WordPress.com hosting
WordPress.com maps one domain to a site; the "different domains per language" URL format needs every language domain to reach the same WordPress, which that hosting does not offer.
What you see
Because of limitations on how domain mapping works with WordPress.com it is not possible to choose the language URLs setting to use different domains per language when sites are hosted with them.
What to do
Either of the other language URL options, with languages in directories or added as a URL parameter, can be used instead of different domains per language.
A different host would be needed if different domains per language were a requirement.
Reference: wpmltriage-2045.
Imported translations and the translation editors
An import writes finished translations; it does not create translation jobs, and the editors work from jobs. The translations are complete on the front end and simply not editable in the Advanced or Classic Translation Editor.
What you see
Whenever you import content using WP All Import and the WPML All Import add-on, you will see the imported post translations perfectly on the front-end. However, you will encounter issues if you try to update them using WPML’s translation editors:
- The Classic Translation Editor displays content in the default language instead of the imported translations
- The Advanced Translation Editor displays blank translations
This is because when you import multilingual content, WPML does not create translation jobs, which are needed for string segmentation.
What to do
To edit or update your imported translations, please switch to the native WordPress editor and use manual translation.
Reference: WPMLAI-168.
Strings registered in English on a site whose default language is not English
Since WPML String Translation 5.0, a string whose language WPML cannot determine is registered in English, by design. The source language of a theme's or plugin's strings is a setting of its text domain, not of the site's default language, and the fix is to set it for that domain.
What you see
When strings are automatically registered for translation in WPML String Translation, they are assigned English as the source language, even if English is not installed or is not the default language on the site.
What to do
Set the language of the text domain: go to WPMLString Translation, scroll down to Utilities, expand Set the original language of themes and plugins and choose the language of the theme's or plugin's domain. The steps, and how to change the source language of individual strings, are in How to Change the Source Language of Strings.
Do not patch the fallback in the plugin's code. The retired known-issue page offered an edit to class-wpml-autoregister-save-strings.php; every update undoes it, and the domain setting is the supported way.
Reference: wpmldev-10164 (earlier wpmldev-3232).