Bogo の言語スイッチャーの並び順(アクセシビリティ対応)
WordPress の多言語化プラグイン Bogo の言語スイッチャーですが、言語コードのアルファベット順に表示されます。例えば、日本語、英語、中国語、ポルトガル語、タガログ語の5言語の場合、次のような順序になります。
- 英語(en_US)
- 日本語(ja)
- ポルトガル語(pt_BR)
- タガログ語(tl)
- 中国語(zh_CN)
これを任意の順序で表示させたい場合、よく紹介されているのは CSS の order プロパティで順序を指定する方法ですが、これでは HTML 上の順序は変わらないため、スクリーンリーダー等では HTML の順序のまま読み上げてしまい、視覚的な表示順序と一致しなくなります。
そこで、CSS を使用せず、PHP によって HTML 上の出力順序そのものを変更する方法です。よくある国旗を非表示にする方法と合わせて紹介します。
functions.php
// Bogoの言語スイッチャーの順序を変更する
add_filter( 'bogo_language_switcher_links', function ( $links ) {
$order = array(
'ja' => 1,
'en_US' => 2,
'zh_CN' => 3,
'pt_BR' => 4,
'tl' => 5,
);
usort( $links, function( $a, $b ) use ( $order ) {
$oa = $order[ $a['locale'] ] ?? 999;
$ob = $order[ $b['locale'] ] ?? 999;
return $oa <=> $ob;
});
return $links;
});
// Bogoの言語スイッチャーの国旗を非表示にする
add_filter( 'bogo_use_flags', '__return_false' );
これで視覚的な順序と HTML の順序が一致します。
ついでに、Bogo の言語スイッチャーは順序なしリスト(ul > li)で出力されます。これを JavaScript と CSS でプルダウンリスト的な操作感にします。WAI-ARIA の aria-expanded と aria-hidden も動的に書き換えています。
HTML
<div id="langSwitcher">
<button type="button" aria-controls="languages" aria-expanded="false">languages</button>
<div id="languages" aria-hidden="true">
<?php echo do_shortcode('[bogo]'); ?>
</div>
</div>
JavaScript (jQuery)
jQuery(function($){
const $langSwitcher = $('#langSwitcher');
const $switchBtn = $('#langSwitcher button');
const $languages = $('#languages');
function languageClose() {
$langSwitcher.removeClass('langOpen');
$switchBtn.attr('aria-expanded', 'false');
$languages.attr('aria-hidden', 'true');
}
$languages.attr('aria-hidden', $langSwitcher.hasClass('langOpen') ? 'false' : 'true');
$($langSwitcher).on('click', function () {
const opened = $langSwitcher.toggleClass('langOpen').hasClass('langOpen');
$switchBtn.attr('aria-expanded', opened ? 'true' : 'false');
$languages.attr('aria-hidden', opened ? 'false' : 'true');
});
// 言語スイッチャー以外をクリックしたら閉じる
$(document).on('click', function (e) {
if ( $langSwitcher.hasClass('langOpen') && !$(e.target).closest('#langSwitcher').length ) {
languageClose();
}
});
// [esc]キーで閉じる
$(window).on('keydown', function (e) {
if (e.key !== 'Escape') {
return;
}
if ($langSwitcher.hasClass('langOpen')) {
languageClose();
return;
}
});
});
CSS(ボーダーや背景等の見た目に関するプロパティは割愛します)
#langSwitcher {
position: relative;
}
#languages {
position: absolute;
top: 100%;
left: 0;
width: 100%;
visibility: hidden;
transform: translateY(-10px);
max-height: 0;
overflow: hidden;
transition:
transform .3s ease,
max-height .3s ease,
visibility 0s linear .3s;
}
#langSwitcher.langOpen #languages {
visibility: visible;
transform: translateY(0);
max-height: 1000px;
transition:
transform .3s ease,
max-height .3s ease,
visibility 0s;
}