CreateIT
CreateIT
BLOG

WP language switcher

WordPress
TAGS: WordPress

WP language switcher

SHARE

Challenge:
to allow users to switch between languages
Solution:
to add custom navigation with links to subsites

A multisite is built in the WordPress CMS feature. We can create a network of sites that use the common administration panel and the same website root url address. Each subsite can use a different language on frontend. A multilingual WP website needs some Lang Switcher to be added.

Language switcher

Here is a PHP snippet for a simple navbar menu with links to subsite homepages. The Lang Menu allows the user to switch between languages. The active CSS class (btn-dark) will highlight the currently active language.

<?php
// header.php
$blog_id = get_current_blog_id();
$en_active_class = 'btn-dark';
$de_active_class = 'btn-primary';
if($blog_id == 2) {
    // DE Language
    $en_active_class = 'btn-primary';
    $de_active_class = 'btn-dark';
}
?>
<ul class="nav">
    <li class="nav-item me-lg-5 me-3">
        <a href="/" class="btn btn-sm <?php echo $en_active_class; ?>">EN</a>
        <a href="/de/" class="btn btn-sm <?php echo $de_active_class; ?>">DE</a>
    </li>
    <li class="nav-item"><a href="/contact" target="_blank" class="text-decoration-none text-white fs-7"><i class="las la-clipboard-list la-2x u-ico-va me-2"></i><?php esc_attr_e( 'Contact'); ?></a></li>
</ul>

Select switcher

We can also prepare a language widget as select, first element ‘Language’ will be added as an option with the disabled parameter. Based on current blog_id we will select a currently active language item. After the option selection, the user will be redirected to proper path url.

// header.php - LangSwitcher as Select
$current_blog_id = get_current_blog_id();
$lang_select_switcher = '<select style="width:90px;" class="form-control" onchange="this.options[this.selectedIndex].value && (window.location = this.options[this.selectedIndex].value);">';
$lang_select_switcher .= '<option disabled="disabled">'. __('Language') .'</option>';
$blogs_ids = (object) array(
    (object) array('blog_id' => 1, 'path' => '/', 'blogname' => 'EN'),
    (object) array('blog_id' => 2, 'path' => '/de/', 'blogname' => 'DE'),
    (object) array('blog_id' => 3, 'path' => '/es/', 'blogname' => 'ES')
);
foreach( $blogs_ids as $lang ){
    $selected = '';
    if( $current_blog_id == $lang->blog_id) {
        $selected = 'selected="selected"';
    }
    $lang_select_switcher .= '<option '. $selected .' value="'. $lang->path .'">'. $lang->blogname .'</option>';
}
$lang_select_switcher .= '</select>';
// render HTML
echo $lang_select_switcher;

Fetch site details from the database

If we don’t want to hardcode blogs_ids in PHP, we can query data from the WordPress database. WP core function get_sites() will fetch all public subsites configured in the Admin Network Area.

// header.php - LangSwitcher as Select
$current_blog_id = get_current_blog_id();
$lang_select_switcher = '<select style="width:90px;" class="form-control" onchange="javascript:location.href = this.value;">';
$lang_select_switcher .= '<option disabled="disabled">'. __('Language') .'</option>';
// fetch list of subsites from database
$blogs_ids = get_sites(['public' => 1]);
foreach( $blogs_ids as $lang ){
    $selected = '';
    if( $current_blog_id == $lang->blog_id) {
        $selected = 'selected="selected"';
    }
    // get subsite blogname value
    $details = get_blog_details( array( 'blog_id' => $lang->blog_id) );
    $lang_select_switcher .= '<option '. $selected .' value="'. $lang->path .'">'. $details->blogname .'</option>';
}
$lang_select_switcher .= '</select>';
// render HTML
echo $lang_select_switcher;

Using the Multisite Language Switcher

An alternative option would be to use the free WP plugin developed by Dennis Ploetner: the Multisite Language Switcher. It adds the backend ability to choose translated versions for every page / post, and also to render links as Lang Switcher on the frontend. After plugin configuration, we can use PHP functions to display lang switcher with custom HTML markup:

// functions.php
// helper function
function get_redirect_urls_for_mapped_sites_using_msls_plugin() {
   $arr = array();
   $blogs = MslsBlogCollection::instance()->get_filtered(false);
   if($blogs) {
      $mydata = MslsOptions::create();
      foreach($blogs as $blog) {
         $language = $blog->get_language();
         $current = ($blog->userblog_id == MslsBlogCollection::instance()->get_current_blog_id());
         if($current) {
            continue;
         } else {
            switch_to_blog($blog->userblog_id);
            $url = $mydata->get_permalink($language);
            $arr[$blog->blog_id] = $url;
            restore_current_blog();
         }
      }
   }
   return $arr;
}

And here is where we can define our custom HTML markup for the menu:

// header.php
// Multisite Language Switcher - display menu with links
<div class="lang-menu-switcher">
    <ul>
        <?php
        $redirect_urls = get_redirect_urls_for_mapped_sites_using_msls_plugin();
        $current_blog_id = get_current_blog_id();
        $sites = get_sites();
        foreach($sites as $site) {
            $class = '';
            if($site->blog_id == $current_blog_id){
                $class = 'active';
            }
            if(isset($redirect_urls[$site->blog_id])) {
                $url = $redirect_urls[$site->blog_id];
            } else {
                $url = $site->path;
            }
            ?>
            <li class="<?php echo $class; ?>"><a href="<?php echo $url; ?>"><?php echo str_replace('/','',$site->path); ?></a></li>
            <?php
        }
        ?>
    </ul>
</div>

That’s it for today’s guideline. Make sure to follow us for other useful suggestions and tips.

Need help?

  • Looking for support from experienced programmers?

  • Need to fix a bug in the code?

  • Want to customize your webste/application?

ADD COMMENT

Your email address will not be published. Required fields are marked *

createIT Contact