Different back-end language for different users?

I’ve been searching the internet for the last hour but I can’t find anything up-to-date to do this (all the suggestions are about plugins that haven’t been updated in ages, see this question).

Is there any way to specify a different back-end language for different users? I like my WP back-end to be in English but all my coworkers prefer it in their own language (Italian), is there any way to live in peace with them?

Props if your method doesn’t rely on URLs (/?lang=it and such) and isn’t a plugin, but a functions.php function.

Thanks, have a great new year!

1
1

We could try to filter the WPLANG option locale (see e.g. this approach from the related list here on the right by @brasofilo, that’s based on this one by @toscho ):

/**
 * Override locale settings for the current (non-admin) user
 */
is_admin() && add_filter( 'locale', function( $locale )
{
    // Modify locale for non-admins (we don't want to override this on the settings pages)
    if( ! current_user_can( 'manage_options' ) )
    {
        // Get admin language for the current user
        $lang = get_user_meta( get_current_user_id(), 'wpse_lang', true );

        // Use 'en_US' as default
        $locale = ! empty( $lang ) ? sanitize_text_field( $lang ) : 'en_US';
    }   
    return $locale; 
} );    

where we check if the current user has the wpse_lang user meta key set, with values like is_IS, da_DK, …

Then we could add the language selection for each user, on the user settings page.

There we could use the wp_dropdown_languages() function, with the get_available_languages() function, to display the select-box for available languages.

Here’s an example by @sanchothefat on how we can add custom user settings.

We can display the user language selection with:

/**
 * Display available language dropdown
 */
function wpse_user_language( $user ) 
{
    // Only display for non-admins, but allow admins to edit for other users
    if( current_user_can( 'manage_options' ) && $user->ID == get_current_user_id() )
        return;

    // Get the current 'wp_lang' settings
    $lang = get_user_meta( $user->ID, 'wpse_lang', true ); 
    ?>
    <table class="form-table">
        <tr id="wpse-lang-selection">
            <th scope="row">
               <label for="wpse_lang">
                   <?php _e( 'WPSE' ); ?> - <?php _e( 'Site Language' ); ?>
               </label>
            </th>
            <td><?php wp_dropdown_languages( 
                    [
                        'id'                          => 'wpse_lang',
                        'name'                        => 'wpse_lang',
                        'languages'                   => get_available_languages(),
                        'translations'                => [],
                        'selected'                    => $lang,
                        'show_available_translations' => false,
                    ] 
                );
            ?></td>
        </tr>
    </table>
    <?php
}
add_action( 'show_user_profile', 'wpse_user_language' );
add_action( 'edit_user_profile', 'wpse_user_language' );

Note that here we re-use the Site Language string, because it’s translated.

The update part is:

/**
 * Update the 'wp_lang' user settings
 */    
function wpse_user_language_save( $user_id ) 
{
    if( current_user_can( 'edit_user', $user_id ) && isset( $_POST['wpse_lang'] ) )
        return update_user_meta( $user_id, 'wpse_lang', $_POST['wpse_lang'] );
    return false;
}
add_action( 'personal_options_update', 'wpse_user_language_save' );
add_action( 'edit_user_profile_update', 'wpse_user_language_save' );

Here’s an example output:

wpse_lang selection

Hopefully you can adjust this to your needs. It would be a good idea to wrap this in a class, where we could initialize it with a custom setup and re-use things for better performance. We might also consider removing the is_admin() check to apply this also on the front-end, but then we might need an extra is_user_logged_in() check.

Leave a Comment