[Resolved] i want to translate a acf field in a author user profile
This thread is resolved. Here is a description of the problem and solution.
Problem: You are trying to translate an ACF custom field in a user profile and display the content on the frontend of your site.
Solution: We recommend implementing the following steps in your child theme's functions.php file to enable translation of the ACF custom field using WPML: 1. Open your active child theme’s functions.php. 2. Paste the provided code into functions.php. 3. Edit the CONFIG section at the top to add your meta keys and toggle emoji stripping if your database isn’t utf8mb4. 4. Log in and visit any page to auto-register your current user’s values. 5. Optionally, run a one-time bulk register for all users by visiting
/wp-admin/?wpml_register_user_strings=1
. 6. Translate the fields in WPML → String Translation under the Domain: 'User Profiles'. 7. Display the translated values using the provided helper function or shortcode.
For detailed steps on how to translate and display the values, refer to the provided instructions in the code comments.
If this solution does not resolve your issue or seems outdated, please check related known issues at https://wpml.org/known-issues/, verify the version of the permanent fix, and confirm that you have installed the latest versions of themes and plugins. If needed, do not hesitate to open a new support ticket at WPML support forum for further assistance.
This is the technical support forum for WPML - the multilingual WordPress plugin.
Everyone can read, but only WPML clients can post here. WPML team is replying on the forum 6 days per week, 22 hours per day.
Background of the issue:
I'm trying to translate an ACF custom field that is displayed in a specific user profile and display the content on the frontend of a site under development.
Symptoms:
No specific issue or error message mentioned.
Questions:
How can I translate an ACF custom field in a user profile using WPML?
I believe I found a solution, which I implemented on the test site and you can now see the ACF field value in String Translation. Let's test this on your live site, and you can check my test install to see how it is working.
I recommend you put the following in a child theme’s functions.php so parent theme updates don’t remove it, or alternately create a custom MU plugin and you could put the code there. In the test site, I added it to functions.php.
1. Open your active child theme’s functions.php.
2. Paste the full code below.
3. Edit the CONFIG section at the top (add your meta keys, toggle emoji stripping if your DB isn’t utf8mb4).
4. While logged in, visit any page (auto-registers your current user’s values).
5. (Optional) Run a one-time bulk register for all users: visit
/wp-admin/?wpml_register_user_strings=1
6. Translate in WPML → String Translation under Domain: “User Profiles.”
7. Display with the helper function or shortcode.
Full code for functions.php (child theme):
/**
* WPML User Meta i18n for ACF User Fields
* Place in your CHILD THEME's functions.php
* Registers per-user meta in WPML String Translation and provides display helpers.
*/
if (!defined('ABSPATH')) { exit; }
/** ─────────────────────────────────────────────────────────────────────
* CONFIG — EDIT THESE FOR YOUR SITE
* ──────────────────────────────────────────────────────────────────── */
if (!defined('WPML_UMI_DOMAIN')) define('WPML_UMI_DOMAIN', 'User Profiles'); // Domain shown in WPML → String Translation
if (!defined('WPML_UMI_STRIP_EMOJI')) define('WPML_UMI_STRIP_EMOJI', false); // Set true if DB isn't utf8mb4 (emoji errors)
if (!defined('WPML_UMI_META_KEYS')) define('WPML_UMI_META_KEYS', serialize(array(
'foobar_test', // ← replace / add your user meta keys to translate, e.g., 'bio', 'tagline'
)));
/** ─────────────────────────────────────────────────────────────────────
* UTILITIES
* ──────────────────────────────────────────────────────────────────── */
if (!function_exists('wpml_umi_meta_keys')) {
function wpml_umi_meta_keys() {
$keys = @unserialize(WPML_UMI_META_KEYS);
return is_array($keys) ? $keys : array();
}
}
if (!function_exists('wpml_umi_strip_emoji')) {
function wpml_umi_strip_emoji($text) {
if (!$text) return $text;
// Minimal emoji strip for non-utf8mb4 DBs
return preg_replace('/[\x{1F300}-\x{1FAFF}\x{2600}-\x{27BF}]/u', '', $text);
}
}
/**
* Register a single user meta key as a WPML string.
*/
if (!function_exists('wpml_umi_register_user_meta_string')) {
function wpml_umi_register_user_meta_string($user_id, $meta_key, $value_override = null) {
$value = ($value_override !== null) ? $value_override : get_user_meta($user_id, $meta_key, true);
if ($value === '' || $value === null) return;
if (WPML_UMI_STRIP_EMOJI) {
$value = wpml_umi_strip_emoji($value);
}
$name = "{$meta_key}_{$user_id}";
// Register via WPML String Translation action API (safe if ST is active)
if (has_action('wpml_register_single_string')) {
do_action('wpml_register_single_string', WPML_UMI_DOMAIN, $name, $value);
}
}
}
/**
* Get translated value (falls back to original if not translated).
*/
if (!function_exists('wpml_umi_user_meta_i18n')) {
function wpml_umi_user_meta_i18n($user_id, $meta_key, $domain = WPML_UMI_DOMAIN) {
$value = get_user_meta($user_id, $meta_key, true);
if ($value === '' || $value === null) return '';
$name = "{$meta_key}_{$user_id}";
// Ensure it's registered (idempotent)
if (has_action('wpml_register_single_string')) {
$maybe = WPML_UMI_STRIP_EMOJI ? wpml_umi_strip_emoji($value) : $value;
do_action('wpml_register_single_string', $domain, $name, $maybe);
}
if (has_filter('wpml_translate_single_string')) {
return apply_filters('wpml_translate_single_string', $value, $domain, $name);
}
return $value; // WPML ST not active → raw value
}
}
/** ─────────────────────────────────────────────────────────────────────
* AUTO-REGISTRATION HOOKS
* ──────────────────────────────────────────────────────────────────── */
/**
* Register the current user's meta on normal requests (quick feedback).
*/
add_action('init', function () {
if (!has_action('wpml_register_single_string')) return;
$user_id = get_current_user_id();
if (!$user_id) return;
foreach (wpml_umi_meta_keys() as $key) {
wpml_umi_register_user_meta_string($user_id, $key);
}
}, 20);
/**
* Re-register when a user profile is updated in wp-admin.
*/
add_action('profile_update', function ($user_id) {
if (!has_action('wpml_register_single_string')) return;
foreach (wpml_umi_meta_keys() as $key) {
wpml_umi_register_user_meta_string($user_id, $key);
}
}, 10, 1);
/**
* Re-register when ACF saves a user form (post_id like "user_123").
*/
add_action('acf/save_post', function ($post_id) {
if (strpos($post_id, 'user_') !== 0) return;
if (!has_action('wpml_register_single_string')) return;
$user_id = (int) substr($post_id, 5);
foreach (wpml_umi_meta_keys() as $key) {
// If you prefer ACF's get_field(), uncomment:
// $acf_val = function_exists('get_field') ? get_field($key, 'user_' . $user_id) : null;
// wpml_umi_register_user_meta_string($user_id, $key, $acf_val);
wpml_umi_register_user_meta_string($user_id, $key);
}
}, 20);
/** ─────────────────────────────────────────────────────────────────────
* SHORTCODE: [wpml_user_meta key="foobar_test" user="7"]
* If user is omitted, uses current logged-in user.
* ──────────────────────────────────────────────────────────────────── */
add_shortcode('wpml_user_meta', function ($atts) {
$a = shortcode_atts(array(
'key' => '',
'user' => '',
), $atts, 'wpml_user_meta');
$meta_key = sanitize_key($a['key']);
if (!$meta_key) return '';
$user_id = $a['user'] !== '' ? (int) $a['user'] : get_current_user_id();
if (!$user_id) return '';
return esc_html( wpml_umi_user_meta_i18n($user_id, $meta_key) );
});
/** ─────────────────────────────────────────────────────────────────────
* ONE-TIME BULK REGISTER (optional)
* Visit as an admin: /wp-admin/?wpml_register_user_strings=1
* Limit to a user: /wp-admin/?wpml_register_user_strings=1&user=7
* ──────────────────────────────────────────────────────────────────── */
add_action('admin_init', function () {
if (!is_admin() || !current_user_can('manage_options') || !isset($_GET['wpml_register_user_strings'])) return;
if (!has_action('wpml_register_single_string')) wp_die('WPML String Translation not available.');
$target_user = isset($_GET['user']) ? (int) $_GET['user'] : 0;
$registered = 0;
if ($target_user > 0) {
foreach (wpml_umi_meta_keys() as $key) {
wpml_umi_register_user_meta_string($target_user, $key);
$registered++;
}
} else {
// Collect users with any configured meta
$user_ids = array();
foreach (wpml_umi_meta_keys() as $key) {
$users = get_users(array(
'meta_key' => $key,
'meta_compare' => 'EXISTS',
'fields' => array('ID'),
'number' => 9999, // increase if needed
));
foreach ($users as $u) { $user_ids[$u->ID] = true; }
}
foreach (array_keys($user_ids) as $uid) {
foreach (wpml_umi_meta_keys() as $key) {
wpml_umi_register_user_meta_string($uid, $key);
$registered++;
}
}
}
wp_die('WPML User Meta i18n: registered strings = ' . (int) $registered);
});
How to translate (after code is added):
1. Go to WPML → String Translation.
2. Domain: choose User Profiles (or search all domains).
3. Find the string named <meta_key>_<user_id> (e.g., foobar_test_7).
4. Enter translation(s) → check “Translation is complete” → Save.
How to display the translated value
In a PHP template:
// For a specific user (ID 7)
echo esc_html( wpml_umi_user_meta_i18n( 7, 'foobar_test' ) );
// For the current logged-in user
echo esc_html( wpml_umi_user_meta_i18n( get_current_user_id(), 'foobar_test' ) );
Anywhere (editor/shortcode):
[wpml_user_meta key="foobar_test" user="7"]
((If you omit user, it uses the current logged-in user.)
Please note: If a string doesn’t appear right away, go to WPML → Support → Troubleshooting and click “Clear the cache in WPML” (and “Remove ghost entries…”)
Please let me know if this resolves the issue, and feel free to use the test site I created to play around with this solution if you like.