bogo dropdown feature

Tailoring Bogo: A Guide to Creating a Dropdown Language Switch

So, I’ve been working on my multilingual portfolio site and decided to give Bogo a go. Here’s how I set it up and tailored it to suit my site.

Setting Up Bogo

  1. First things first, I downloaded and installed Bogo. There’s a new “Languages” tab where you can select the languages you want to support.activate language pack
  2. In the post or page editor, there’s a new sidebar section for adding translations. Clicking the button duplicates the content into a new post or page.add translation
  3. Then, it’s just a matter of editing the duplicated post or page and translating the text manually. I experimented with changing the slug of the duplicated page and it worked like a charm. But for my purposes, I decided to keep the same slug.
  4. Bonus: There’s a language switcher for the dashboard. The default language of new posts and pages will match the existing language set.switch in dashboard

Customising the Language Switch

By default, the language switcher is a list that shows all active languages, even for pages without translations. But here’s how I turned it into a dropdown list, thanks to a helpful note from i-nob.

Adding the Switch via Site Editor

In my case, I wanted the language switch in the navigation bar.

HTML
<div class="display-item"></div>
<div class="wp-block-bogo-language-switcher">[bogo]</div>

Modifying the Display Element with PHP

Here’s what I did:

  • Removed the flag icon from the language switch button
  • Altered the language switch button’s notation

Why I removed the flag

I removed the flag because it only represents the country or region. People living outside may also use the same language.

PHP
//Hide Bogo flag
add_filter( 'bogo_use_flags','bogo_use_flags_false');
function bogo_use_flags_false(){
	return false;
}

//Change language display name
add_filter( 'bogo_language_switcher_links', 'custom_bogo_language_title_name', 10, 2 );
function custom_bogo_language_title_name( $links ) {
  foreach ( $links as $code => $name ) {
    if ( $name['lang'] === 'en-GB' ) {
      $links[$code]['title'] = 'English';
      $links[$code]['native_name'] = 'ENG';
    } elseif ( $name['lang'] === 'ja' ) {
      $links[$code]['title'] = '日本語';
      $links[$code]['native_name'] = '日本語';
    } elseif ( $name['lang'] === 'zh-HK' ) {
      $links[$code]['title'] = '中文';
      $links[$code]['native_name'] = '中文';
    }
  }
  return $links;
}

Controlling Movement and Display with JavaScript

Next, I made the switch a dropdown by:

  • Showing the current language as the default item
  • Hiding language options without translations
  • Including code to calculate the dropdown’s height based on the number of list items, for a nice expanding animation
  • Allowing click triggers only if other translations are available
  • Adding a class to the dropdown if there are no other translations, for further styling later on
JavaScript
//Bogo - hide li item if no translation
document.addEventListener("DOMContentLoaded", function() {
    const listItems = document.querySelectorAll('.bogo-language-switcher li');

    listItems.forEach(item => {
        if (!item.querySelector('a')) {
            item.style.display = 'none';
        }
    });

});


//Bogo - dynamic dropdown height
document.addEventListener("DOMContentLoaded", function() {
    // Get the ul element by class name
    const dynamicList = document.querySelector('.bogo-language-switcher');

    // Get the number of visible list items
    const visibleListItems = dynamicList.querySelectorAll('li:not([style*="display: none"])');
    const numberOfVisibleItems = visibleListItems.length;

    // Add class to display if only 1 visible item
    if (numberOfVisibleItems === 1) {
        const display = document.querySelector('.display-item');
        display.classList.add('bogo-disable');
    }

    // Subtract one from the count if necessary
    const adjustedNumberOfItems = Math.max(0, numberOfVisibleItems - 1);

    // Set the value of --list-items CSS variable
    document.documentElement.style.setProperty('--list-items', adjustedNumberOfItems);
});


//Bogo dropdown
jQuery(function($) {
    let selectBox = $('.wp-block-bogo-language-switcher');
    let selectItems = $('.wp-block-bogo-language-switcher li');
    let display = $('.display-item');
    let displayButton = $('.display-item:not(.bogo-disable)');

    const currentLang = $('.bogo-language-switcher li.current').attr('class').split(' ')[0];
    display.addClass(currentLang); // Add current language code as a class to display-item

    const firstLang = $('.bogo-language-switcher > .current span').find('.current');
    const firstLangName = firstLang.first().text();
    display.text(firstLangName);
    display.append('<span class="arrow"></span>');

    let selectBoxFlag = false;
    $(firstLang).css('background','#ccc').attr('tabindex', -1).removeAttr('href');
    displayButton.on('click', function() {
        if (selectBoxFlag === false) {
            selectBoxFlag = true;
            display.addClass('active');
            selectBox.addClass('active');
        } else {
            selectBoxFlag = false;
            display.removeClass('active');
            selectBox.removeClass('active');
        }
    });
    selectItems.on('click', function() {
        $(this).find('a').trigger('click');
    });
});

Sprucing Up the Appearance with CSS

Finally, I polished the dropdown’s look with these settings:

  • Aligned the language switch text to the left
  • Changed the text and background colour on hover
  • Altered the text colour when no other translations are available
CSS
/* Dropdown */
.bogo-dropdown {
  gap: 0;
  align-items: flex-start;
  height: 44px;
}

/* Language Switcher */
.bogo-language-switcher {
  display: flex;
  flex-direction: column;
  border: 1px solid #CACACA;
  border-top: 0;
  border-radius: 0 0 4px 4px;
  position: absolute;
  margin: 0;
  padding: 0;
  width: 96px;
  box-sizing: border-box;
}

.bogo-language-switcher li {
  cursor: default;
  box-sizing: border-box;
  padding: 4px 8px!important;
  text-align: left;
}

.bogo-language-switcher li a {
  text-decoration: none;
  font-weight: 600;
}

.active .bogo-language-switcher li:hover {
  background: var(--wp--preset--color--contrast);
}

.active .bogo-language-switcher li:hover a {
  color: var(--wp--preset--color--accent);
}

.bogo-language-switcher .ja {
  order: 1;
}

.bogo-language-switcher .en-GB {
  order: 2;
}

/* Display Item */
.display-item {
  transition: 0.15s ease;
  width: 96px;
  border: 1px solid #CACACA;
  border-radius: 4px;
  padding: 8px;
  text-align: left;
  border-radius: 4px 4px 0 0;
  border-bottom: 1px solid #FDFFFA;
  padding-bottom: 0;
  font-weight: 600;
}

.bogo-language-name a {
  display: block;
  width: 100%;
  color: #333;
}

/* Arrow */
.arrow {
  width: 13px;
  height: 13px;
  display: inline-block;
  position: relative;
  bottom: -8px;
  left: -10px;
  transition: 0.4s ease;
  margin-top: 2px;
  text-align: left;
  transform: rotate(45deg);
  float: right;
}

.arrow:before,
.arrow:after {
  position: absolute;
  content: '';
  display: inline-block;
  width: 12px;
  height: 3px;
  background-color: var(--wp--preset--color--contrast);
  transition: 0.4s ease;
}

.arrow:after {
  transform: rotate(90deg);
  top: -5px;
  left: 5px;
}

/* Active Arrow */
.display-item.active .arrow {
  transform: rotate(45deg) translate(-5px, -5px);
}

.display-item.active .arrow:before {
  transform: translate(10px, 0);
}

.display-item.active .arrow:after {
  transform: rotate(90deg) translate(10px, 0);
}

/* Active List */
.display-item.active ul {
  opacity: 0.3;
  height: 108px;
}

/* Language Switcher Animation */
.wp-block-bogo-language-switcher .bogo-language-switcher {
  height: 0;
  overflow: hidden;
  padding-bottom: 4px;
  transition: 0.4s ease;
}

/* CSS Variable for Height */
:root {
  --item-height: 34px;
}

.wp-block-bogo-language-switcher.active .bogo-language-switcher {
  height: calc(var(--item-height) * var(--list-items));
  overflow: auto;
  padding-bottom: 0;
  -ms-overflow-style: none;
  scrollbar-width: none;
}

/* Disabled Styles */
.bogo-disable {
  color: var(--wp--preset--color--accent-5);
}

.bogo-disable .arrow:before,
.bogo-disable .arrow:after {
  background-color: var(--wp--preset--color--accent-5);
}

Room for Improvement?

I’ve been pondering whether users who speak different languages will understand the dropdown as it only indicates the current language at first glance, especially if they land on a page in a language they’re not familiar with. I’m considering conducting some user tests to find out. Also, I’m wondering if I should alert users when they try to click the language switch on a post that’s only available in one language. If they feel confused, I’ll add a tooltip for this scenario.


Comments

Leave a Reply

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