When managing multilingual content in WordPress with WPML, connecting translations manually can be tedious, especially for large-scale sites. In this guide, we’ll show you how to automatically link translations across multiple languages using a custom PHP function.
Why Automate Translation Connections?
WPML manages translations using a trid
(Translation Group ID), which links different language versions of a post. Manually setting these connections through the WPML interface can be time-consuming. Automating this process allows for:
- Faster translation linking
- Consistency across translations
- Reduced manual errors
The Custom PHP Function
Below is a PHP function that connects translations automatically by modifying the WPML translations table.
function connect_translations_multiple_languages($original_post_ids, $translations_by_language, $default_language = 'it') {
global $wpdb;
// Get the correct table name with prefix
$translations_table = $wpdb->prefix . 'icl_translations';
$total_updated_count = 0; // Tracks total updates across all languages
$debug_log = []; // Tracks debug information
foreach ($translations_by_language as $language_code => $translated_post_ids) {
$updated_count = 0; // Tracks updates for the current language
foreach ($original_post_ids as $index => $original_post_id) {
$translated_post_id = $translated_post_ids[$index] ?? null;
// Skip if there is no translated post for this index/language
if (!$translated_post_id) {
continue;
}
// Fetch the translation group ID (`trid`) for the original post
$trid = $wpdb->get_var(
$wpdb->prepare(
"SELECT trid FROM {$translations_table} WHERE element_id = %d AND language_code = %s AND element_type = %s",
$original_post_id,
$default_language,
'post_s'
)
);
// Log debug info
$debug_log[$language_code][] = [
'original_post_id' => $original_post_id,
'translated_post_id' => $translated_post_id,
'trid' => $trid ? $trid : 'NOT_FOUND',
];
// Skip if no `trid` found
if (!$trid) {
continue;
}
// Add or update the `wp_icl_translations` table for the translated post
$wpdb->replace(
$translations_table,
array(
'element_id' => $translated_post_id,
'element_type' => 'post_s',
'trid' => $trid,
'language_code' => $language_code,
'source_language_code' => $default_language,
),
array(
'%d', '%s', '%d', '%s', '%s'
)
);
// Update post meta for the translated post
update_post_meta($translated_post_id, '_wpml_import_language_code', $language_code);
update_post_meta($translated_post_id, '_wpml_import_source_language_code', $default_language);
update_post_meta($translated_post_id, '_wpml_import_translation_group', $original_post_id);
// Increment counters
$updated_count++;
}
// Log the number of items updated for this language
$total_updated_count += $updated_count;
}
// Return details and debug info
$debug_message = '<br><strong>Debug Info:</strong><pre>' . print_r($debug_log, true) . '</pre>';
return "Translations connected successfully. {$total_updated_count} items were updated in total." . $debug_message;
}
How It Works
- Retrieve Translation Group ID: The function fetches the
trid
from thewp_icl_translations
table for the original post in the default language. - Loop Through Translations: It iterates over the provided translations, linking them to the same
trid
. - Update Database and Metadata:
- It inserts or updates the translation record in
wp_icl_translations
. - It adds metadata for tracking translation assignments.
- It inserts or updates the translation record in
Example Usage
To execute the function automatically, you can hook it into WordPress using admin_init
:
add_action('admin_init', function () {
$original_post_ids = [11313, 11333]; // Original post IDs in the default language
// Translations for multiple languages
$translations_by_language = [
'en' => [11404, 11405], // Translations for English
'fr' => [11500, 11501], // Translations for French
'de' => [11600, 11601] // Translations for German
];
$result = connect_translations_multiple_languages($original_post_ids, $translations_by_language);
// Show result as admin notice
add_action('admin_notices', function () use ($result) {
echo '<div class="notice notice-success"><p>' . $result . '</p></div>';
});
});
Breakdown of the Hook:
admin_init
: Runs when an admin page loads, ensuring the function executes only in the backend.admin_notices
: Displays a success message in the WordPress admin panel.
Conclusion
By using this approach, you can automate the process of connecting WPML translations across multiple languages, saving time and reducing errors. Whether you’re managing a multilingual blog, e-commerce store, or corporate website, this method ensures that all translations remain properly linked within WPML.
For further customization, you can modify the function to work with custom post types, WooCommerce products, or other WPML-compatible elements.