Sending emails to your site’s users in the language they prefer is important. For this purpose, WPML offers an API to store the user’s preferred language while they are using the site and then apply this preference when sending emails to them.

This document explains to plugin and theme authors how to integrate their products with the standard WordPress wp_mail() function in the preferred language context.

When do you need to send per-user localized emails?

Here are examples that illustrate some typical cases where you need to send emails in user-preferred language.:

  • You are a site administrator sending newsletter to subscribers: the site administrator is French and he displays a newsletter interface in the French language. Result: all emails will be sent in French. As your subscribers come from all around the world, many will not understand this email.
  • You are running a social networking site: members of this site can publish their photos. Other members can like and star those photos – when they like then, the image author will be informed by email.Now consider this scenario:
    1. Mathias, who is German, published his photo.
    2. His friend Pierre, who is French comes across Mathias’ photo and clicks the Like button.
    3. Because during this action, Pierre has been displaying the page in French, Mathias will get an email notification in French.
  • You are running an e-commerce site:  if some product is temporarily unavailable, users can leave their email to be informed when the product is back in stock. A Japanese visitor leaves his email under some of the products. Then the administrator of the site, who is Spanish, updates the availability. Result: the Japanese customer gets an automatic email “Product x is available again” in Spanish, not Japanese.

There are many more similar examples, and you are the perfect person to know if this will present an issue for your plugin or theme.

In all these cases we need to somehow to store the recipient’s preferred language and then, switch for a moment to this language while sending emails.

Wrapping the wp_mail() function with WPML specific code

When you are sending emails you need to add three additional steps to your plugin or theme code:

  1. Switch language context to the one prefered by the email recipient.
  2. Then run all your code for actually sending the email.
  3. Switch the language back to the site’s language.

Second step is probably ready at this point. The only thing to do is to add two additional lines, specific to WPML – you only need to add the lines that are bolded.

$email = get_option('receiver-email');

// Switch language context…
do_action('wpml_switch_language_for_email', $email);

// your code for sending email:
$subject = __('Hello, World!', 'text-domain');

$message = __('This is our newsletter', 'text-domain');

wp_mail($email, $subject, $message);

// switch language back
do_action('wpml_restore_language_from_email');

As you can see, the changes are small but you need to remember about the following two important points.

1. Switch the language before the very first email content is retrieved

Remember that you are switching the language to translate the email content. This is why you need to remember to set correct language before you retrieve any email content – subject or message content.

The following code will not work:

$email = my_func_to_get_receiver_email();
$subject = my_func_to_get_title(); // will come in site’s lang
$message = my_func_to_get_msg_body(); // will come in site’s lang

do_action('wpml_switch_language_for_email', $email);
wp_mail($email, $subject, $message);
do_action('wpml_restore_language_from_email');

Instead you should use:

$email = my_func_to_get_receiver_email();
do_action('wpml_switch_language_for_email', $email);
$subject = my_func_to_get_title(); // will come in receiver’s lang

$message = my_func_to_get_msg_body(); // will come in receiver’s lang
wp_mail($email, $subject, $message);
do_action('wpml_reset_language_after_mailing');

2. Do not send emails to an array of receivers

The wp_mail() function allows to pass the $email as a parameter array of emails. Unfortunately, this is prohibited if you want to make email content translatable.

So if you have a code that is not working, like this one:

$emails = my_func_get_emails_array(); // array(email1, email2...)
do_action('wpml_switch_language_for_email', $emails); // will not work

$subject = my_func_to_get_title();
$message = my_func_to_get_msg_body();
do_action('wpml_restore_language_from_email');

You should rewrite it to:

$emails = my_func_get_emails_array(); // array(email1, email2...)

foreach($emails as $email) :
do_action('wpml_switch_language_for_email', $email); // now is ok
$subject = my_func_to_get_title();
$message = my_func_to_get_msg_body();
do_action('wpml_restore_language_from_email');
endforeach;

Store recipient’s language

Language information for WP users

If your recipients are registered as standard WordPress users, you do not need to save the language information and create a hook. You can simply inform your users that they can set their preferred language in the WordPress admin under Profiles->Your profile.

This information is stored in a regular user meta field, so if for some reason you do want to retrieve it, you can use this handy snippet:

$user = get_user_by( 'email', $email );
if ( $user && isset( $user->ID ) ) {
 $lang = get_user_meta( $user->ID, 'icl_admin_language', true );
}

When recipients are not regular WP users

Every time your plugin or theme register an email address, you should also save the recipient’s prefered language. You do not require any special place or data type for this. The only thing you need to do is to add a filter which will return the language information. The filter’s name is wpml_user_language.

Example code which you need to implement might look like this:

add_filter(‘wpml_user_language’, ‘my_recipients_language’, 10, 2);

function my_recipient_language($lang, $email) {
return get_language_from_my_database($email); // implement it in  your plugin/theme
}

Language widget

If you provide some front-end user interface with configuration panel for your subscribers, you can ask them for their language with the following action hook:

do_action('wpml_user_language_switcher', array('mail'=>'mail@example.com') );

Please note that you need to replace the mail@example.com with the real email of a current subscriber.

This code will display select box with available languages. When a subscriber selects one, this value will be sent through an AJAX call to the server.

Then, you need to save this data in your database tables. To do this, add a hook for wpml_user_language_switcher_save filter, like this:

add_filter('wpml_user_language_switcher_save', 'my_func', 10, 3);

function my_func($saved, $email, $language) { // your code to save email - language pair, i.e.:
save_language_in_my_database($email, $language);
// if you saved data correctly, return true
return true;
}

If your filter will not return a value of true, or you don’t have a filter for that at all, WPML will try to save the language information in the user meta table (see next chapter).

Sending emails to addresses that are not stored

Sometimes you need to send emails to addresses which are not in any database table. Because recipients are not in your database, you are not storing any recipient’s language preferences either.

For those cases, WPML expects that language code will be available in one of these three global variables:

  • $_POST['wpml_user_email_language']
  • $_GET['wpml_user_email_language']
  • $GLOBALS['wpml_user_email_language']

How to translate emails

Translating email content is the same as translating any other strings in your site. For more detailed information on this topic, please visit our String Translation documentation page.

In short, make sure that the following is applied to all strings that are used as email content (subject or mail body):

  • If they are static strings, make sure that they are localised with gettext functions _e() or __()).
  • If they are saved in WordPress options table and retrieved using the get_option() function, you need to “inform” WPML that they are translatable too. This is done using the Language Configuration File.

If those conditions are met in your plugin or a theme, users will be able to translate them on the WPML->String Translation page.

Practical example

To see a more practical example of information presented on this page, please visit our blog post about using WPML Mail API Integration with the Sensei plugin.