WordPressの多言語化プラグインBogoにはまった話

Web関連

WordPressの多言語化プラグインBogoにはまった話

はまった症状

この記事を書いているのは2026年の正月です。WordPressを使っている当サイトで、年末まで支障なく稼働していたBogoプラグインを用いたバイリンガルサイト機能が、いきなり動作不良を起こしました。症状は以下のような感じです。

  • 固定ページに設置した英語版フロントページが表示されず、常に日本語版となる。”/en/”が”/”にリダイレクトされる。
  • 英語版の記事が、記事によって表示されたり、日本語のトップページにリダイレクトされたりする。
  • 環境はさくらインターネットのレンタルサーバ・スタンダードプラン。

あれこれ試すもののどうにも解決せず、正常に動いていた時期のバックアップに復旧しても改善なし。最後には新規にWordPressをインストールして構築しなおして、試しましたが症状は変わらず。

困り果てました。

すでに多数の記事をBogoを使い、相互に参照するかたちで公開していたため、いまさらURLの構造が変わる別の仕組みの導入は考えられず。

以下、丸一日かけて、なんとか力技でトラブル発生前に近い動作をするようにねじ伏せた顛末記となります。

ご覧になっている頃には、すでに解決済みの話題かもしれませんが、もしかしたら、、、同様のお悩みをおもちの方もいらっしゃるかもしれませんので、記録に残しておきます。

まずは結論から

まどろっこしい前口上抜きで結論を知りたいことと思いますので、わたしの取った対策を以下にまとめます。

“-“を含むスラッグのついた記事がリダイレクトされる

不安定動作の挙動を調べていくうちに、フロントページ以外の記事がルートにリダイレクトされてしまうのは、スラッグに”-“(マイナス記号)が使われている記事に限定していることがわかりました。たとえば”itc-curriculum”などです。

ですから、対策は簡単で、”-“を含むスラッグを修正するだけです。(とは言っても、張り巡らしたリンク関係の修正を考えると、とても簡単とは言い切れませんけれど、、、。)

先の”itc-curriculum”なら”itccurriculum”または”itc_curriculum”とすれば、問題なく表示されます。アンダースコアは影響しないようです。

なお、カスタムURLのカテゴリーなどが”-“を含んでいる分には、動作に影響はありません。

フロントページはクエリで対策

以上で記事の対策はなんとかなりましたが、フロントページがどうにもなりません。

とにかく何でもやってみようと、ふと思いついたのが、URLに言語属性指定”?lang=en”を付けてみることでした。

これが大ヒットで、”/en/”では”/”にリダイレクトされてしまうのに、”/en/?lang=en”では見事に英語のフロントページが表示されました。

対策の糸口がみつかりましたので、”/en/”または”/en”で終わるURLに強制的に”?lang=en”を付加する方法を考えます。

メニューであれば、たとえば”ENGLISH”というメニューにカスタムリンク”/en/?lang=en”を設定して割り当てれば事足りますが、サイトロゴマークやパンくずリストなどのリンクはその方法は使えません。

いちばん簡単なのは、はやりクライアントサイドで処理する方法かと思います。

jQueryとJavaScriptを使います。

//
// Bogoの不調回避
// 2025/01/05 msat
//
$(document).ready(function() {
	//
	// aタグをスキャンし/en/で終わるURLに ?lang=en を追記する
	//
	$("a").each(function() {
		var href_prop = this.href;
		if ( href_prop.substr( -3 ) == '/en' ) {
			$(this).attr( 'href', href_prop + '/?lang=en' );
		} else
		if ( href_prop.substr( -4 ) == '/en/' ) {
			$(this).attr( 'href', href_prop + '?lang=en' );
		}
	});
});

お使いのテーマにもよるでしょうが、以上のコードを子テーマのjavascript.jpに追記すれば速効で目的は果たされると思います。(うまく動作しない場合は、まずキャッシュを疑って下さい。)

原因は不明

2026年1月時点で、原因は不明です。

わたしの環境に依存するのか??とも考えますが、それにしても不可解です。

心当たりの方はぜひ教えて下さい。

参考 その1(Bogoのデータベース構造)

原因究明のためにBogoのデータベースの構造について調べたので、共有させて下さい。この構造がわかると、不整合が起きたときに、自力で修正できると思います。

ただし、調べたのは日英の二カ国語の場合のパターンですので、もっとたくさんの言語を扱うケースの参考にはならないかもしれません。

Bogoが使用しているテーブルは wp_postmeta です。

日英の記事1セットにつき、以下の4つのレコードが作成されます。

記事

post_id

meta_value

meta_key

備考

ページA(日本語)

100

[site URL]/?post_id=100

_original_post

固定ページ

ページA(英語)

102

[site URL]/?post_id=100

_original_post

ページA(日本語)

100

ja

_locale

ページA(英語)

102

en_US

_locale

記事B(日本語)

200

[site URL]/?p=200

_original_post

記事

記事B(英語)

202

[site URL]/?p=200

_original_post

記事B(日本語)

200

ja

_locale

記事B(英語)

202

en_US

_locale

上記のmeta_value中のURLクエリpost_idまたはpの値が自身のpost_idと一致する言語が、そのサイトの母語というわけです。

参考 その2(メニューをBogoスイッチャー化する)

作業の過程で、メニューにBogoスイッチャーを適用させるスクリプトも同じ仕組みでできると思いつき、つくってみました。もちろん、”?lang=en”付です。

ウィジェットなどで配置したBogoスイッチャーの内容をJavaScriptで拾って、メニューのリンクを置き換えるだけです。(参照元のBogoスイッチャーが邪魔なら、display:none; で消しておけばよいでしょう。)

ショートコードとCSSでメニューにBogoスイッチャーを配置されている方もいらっしゃいますが、この手法だといろいろ面倒がなくていいなと思っています。

あくまでも参考ですが、以下に紹介します。

//
// Bogoの不調回避 & メニュー対応
// 2025/01/05 msat
//
$(document).ready(function() {
	//
	// aタグをスキャンし/en/で終わるURLに ?lang=en を追記する
	//
	$("a").each(function() {
		var href_prop = this.href;
		if ( href_prop.substr( -3 ) == '/en' ) {
			$(this).attr( 'href', href_prop + '/?lang=en' );
		} else
		if ( href_prop.substr( -4 ) == '/en/' ) {
			$(this).attr( 'href', href_prop + '?lang=en' );
		}
	});
	//
	// BOGOのスイッチャーウィジェットのURLをメニューに反映させる
	//
	$("ul.menu-header>li div.item-label").each( function() {
		const label_jp = 'JAPANESE';
		const label_en = 'ENGLISH';
		const bogo_jp = 'Japanese';
		const bogo_en = '英語';
		const bogo_id = 'div#bogo_language_switcher-7';
		var targetObj;
		var replaceUrl;
		if ( $(this).text() == label_jp ) {
			targetObj = $(this).parent().parent();
			$("div#bogo_language_switcher-7 span.bogo-language-name a").each( function() {
				if ( $(this).attr( 'title' ) == bogo_jp ) {
					replaceUrl = this.href;
					if ( location.hash != "" ) replaceUrl += location.hash;
					$( targetObj ).attr( 'href', replaceUrl );
					return false;
				}
			});
			return false;
		} else
		if ( $(this).text() == label_en ) {
			targetObj = $(this).parent().parent();
			$( bogo_id + " span.bogo-language-name a" ).each( function() {
				if ( $(this).attr( 'title' ) == bogo_en ) {
					replaceUrl = this.href;
					if ( location.hash != "" ) replaceUrl += location.hash;
					$( targetObj ).attr( 'href', replaceUrl );
					return false;
				}
			});
			return false;
		}
	});
});

このコードは、WordPressの設定環境に依存するので、ご自身でカスタマイズしてお使いいただく必要があります。

要点は、constで定義してある定数をご自身の環境にあわせて変更することです。

  • label_jp:メニューの文字(英語ページから日本語ページに誘導するメニュー)
  • label_en:同(その逆)
  • bogo_jp:Bogoスイッチャーのaタグのタイトル属性の内容
  • bogo_en:同
  • bogo_id:Bogoスイッチャーのブロック識別子

以上、この仕組みは誠に具合がよく、丸一日の苦労が報われる成果物をいただいたのかもしれません。

気に入ったらお使い下さい。

タイトルとURLをコピーしました