【WordPress】多言語化プラグイン「Bogo」の言語切替をドロップダウン型にした話

最近のマイブームはソロプレイできるボードゲームで遊ぶこと!

どうも、フリーランスのWeb制作者のi-nob(@inobapen)です。

WordPressで多言語化プラグインとして人気のある「Bogo」ですが、検索してみると結構言語切替の見た目や機能などをカスタマイズしている事例を多く目にします。

今回は、Bogoの言語リストをこのような

画像1

上に現在言語表示が付いていて、下に開閉式のドロップダウン型にしたというケースをご紹介したいと思います。

Bogoが標準で用意している言語切替リストをカスタマイズしていく方向で進めていきます。

今回は、日本語と英語の2か国語のリストをカスタマイズした事例です。

フッターウィジェットのカスタムHTMLを使っているパターンのためfunctions.phpで下準備が必要ですが、普通にphpのテンプレートファイルに入れ込む場合は下準備は不要です。

おまけで、今回の実装はWordPressの人気無料テーマ”Cocoon”で実装した際にハマった点も綴っていきますので、最後までお付き合い頂ければ幸いです。

また、実装に伴って以下のteratailの投稿にとても助けられました。

さて、早速行ってみましょう!

1:ショートコードをカスタムHTMLで使えるようにする

Bogoで言語切替を表示するのはショートコードで [bogo] というものが準備されていて簡単に呼び出し・出力ができます。

今回はカスタムHTMLで使えるようにfunctions.phpに以下の一文を加えておきましょう。

// カスタムHTMLでショートコードを使用
add_filter( 'widget_text', 'do_shortcode' );

2:フッターウィジェットにカスタムHTMLを追加して記述する

CocoonのフッターウィジェットはPC3カラム・モバイル用に分かれていますが、今回は以下の画像のように

画像2

フッター左とモバイル用にカスタムHTMLを加えていきましょう。

ここが後のおまけに繋がるとは、この時は思いもしなかったのであった…

さて、HTMLは簡単で、両方とも以下のように書きました。

<div class="display-item"></div>
[bogo]

divは現在言語の表示用で、下のショートコードが実際の言語リストの部分ですね。

phpのテンプレートを使用する場合はdo_shortcodeを通す形でショートコードを書いてあげて下さい。

Bogoのショートコードで出力されるものを細かく書くと、実際には以下のように出力されます。

<div class="display-item"></div>
<ul class="bogo-language-switcher">
 <li class="en-US en first">
   <span class="bogo-language-name">
     <a rel="alternate" hreflang="en-US" href="https://hoge.com/en/" title="English">English</a>
   </span>
 </li>
 <li class="ja current last">
   <span class="bogo-language-name">
     <a rel="alternate" hreflang="ja" href="https://hoge.com/" title="日本語" class="current" aria-current="page">日本語</a>
   </span>
 </li>
</ul>

ポイントは現在表示されている言語のli要素とその最下層のa要素に"current"というクラスが付与される点。

これを踏まえて次はjQueryで動きや表示を制御していきます。

3:jQueryで動きや表示を制御する

実際に書いたコードがこちらです↓

jQuery(function($) {
 let selectBox = $('.bogo-language-switcher');
 let selectItems = $('.bogo-language-switcher li');
 let display = $('.display-item');

 const firstLang = $('.bogo-language-switcher > .current span').find('.current');
 const firstLangName = firstLang.first().text();
 display.text(firstLangName);

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

あまり綺麗ではないのが申し訳ないところですが…

4行目のfirstLang周辺は現在言語表示枠に現在言語のテキストを表示させる処理です。普通は5行目の部分は firstLang.text(); で良いのですが、Cocoonのウィジェットの特性でこうしなければ上手くいきませんでした。(おまけ参照)

後は現在表示枠の表示切替と、リストの中にある現在言語の背景色をグレーにしたり無効化する処理をしています。

 11-19行目で言語リストの開閉制御をしています。(現在言語表示枠クリックで開閉)

20行目以降で、クリックした言語の遷移をtriggerのclickでイベント発火させるような処理をしています。

4:CSSで見た目を整える

.bogo-language-switcher {
 display: -webkit-box;
 display: -ms-flexbox;
 display: flex;
 -webkit-box-orient: vertical;
 -webkit-box-direction: normal;
     -ms-flex-direction: column;
         flex-direction: column;
 width: 200px;
 border: 1px solid #c5c5c5;
}
.bogo-language-switcher li {
 cursor: default;
 box-sizing: border-box;
 padding: 2px 10px;
 text-align: center;
}
.bogo-language-switcher .ja {
 -webkit-box-ordinal-group: 2;
     -ms-flex-order: 1;
         order: 1;
}
.bogo-language-switcher .en-US {
 -webkit-box-ordinal-group: 3;
     -ms-flex-order: 2;
         order: 2;
}
.display-item {
 width: 200px;
 box-sizing: border-box;
 border: 2px solid #c5c5c5;
 border-radius: 10px;
 padding: 5px 10px;
 text-align: center;
}
.bogo-language-name a {
 display: block;
 width: 100%;
 color: #333;
}

見た目を整えていきましょう。

ちなみに、日本語と英語をorderプロパティで順序固定しています。

これで完成ですが、見た目はお好みで変えて下さればと思います。

おまけ:PC・モバイル用ウィジェットでハマった話

さて、お待ちかねのおまけです。

Cocoonではモバイル用に専用のフッターウィジェットが準備されていて、そこにもPC用と同じようにカスタムHTMLを書いて、ブラウザで確認したところ…現在言語表示枠が [ 日本語日本語 ] という二重に表示される結果に…

その際、jQueryの方では

 const firstLang = $('.bogo-language-switcher > .current span').find('.current');
 const firstLangName = firstLang.text();
 display.text(firstLangName);

こんな風に書いていましたが、ウィジェットがPC・モバイル用と2つあるためにcurrentクラス付きのa要素が2つ発生し、2回分現在言語の取得を行っていたのがこの原因でした。

それを避けるために、以下のように修正しました↓

 const firstLang = $('.bogo-language-switcher > .current span').find('.current');
 const firstLangName = firstLang.first().text();
 display.text(firstLangName);

2行目のfirstメソッドで最初のcurrent付きa要素からだけ、言語名を取得するすればOKだった…というオチでした。

…というわけで、Bogoのカスタマイズの一助になれば嬉しいです。

ではまた!

いいなと思ったら応援しよう!