PukiWiki を使った国際化サイトの作り方のヒントを事例を踏まえて紹介します。

by toydev?

前提

誰でも書き込みができるいわゆる Wiki としてではなく、単純な CMS として個人サイトで PukiWiki を使っている事例を元にしています。

書き込みをする人は管理者一人だけであり、全体のコントロールが容易であることが前提です。Wiki として不特定多数が自由に書き込める状況で採用した場合に何が起こるかは予測の範囲に入っていません。

概要

  • 最小限の設定変更だけで UI とコンテンツの表示言語を制御します。最小構成時点ではPukiWiki 本体はそのまま使用するため改造が必要ありません。
  • 各言語のコンテンツは独立します。例えばページ一覧には現在表示されている言語のページしか表示されません。
  • 表示言語の決定ルールは任意です。事例では URL のサブドメインの先頭に ja や en が入っていることを前提とし、その文字列で表示言語を決定する方法を紹介します。
  • 以上を最小構成とし、発展のヒントは補足として紹介します。例えば言語別のサイト間をつなげるための様々なアイデア紹介です。

具体的な設定変更内容

必要な設定変更は2つだけです。

  • 言語決定ルールに従って LANG 定数を動的に設定する。
  • LANG 定数によって読み込むデータを動的に設定する。

それぞれについて説明します。

言語決定ルールに従って LANG 定数を動的に設定する。

LANG 定数の定義は pukiWiki.ini.php にあり、デフォルトの定義は日本語(ja)固定になっています。

/////////////////////////////////////////////////
// Language / Encoding settings

// LANG - Internal content encoding ('en', 'ja', or ...)
define('LANG', 'ja');

以上の設定を元に読み込まれる ja.lng.php と en.lng.php が切り替わり UI の表記が自動で切り替わります。これは PukiWiki 標準の機能です。 対応言語を増やしたい場合は xx.lng.php の設定を追加します。 (追加しますと簡単に書きましたが、標準では ja と en しか用意されていないため自分で作成する必要があります。)

何らかのルールに従って LANG の値を動的に設定するだけで UI の表示言語の切り替えは完了です。

例えばサブメイン(jp.xxx.yyy の先頭の jp の部分)によって表示言語を切り替える簡単な実装は以下の通りです。

/////////////////////////////////////////////////
// Language / Encoding settings

// LANG - Internal content encoding ('en', 'ja', or ...)
define('LANG', current(explode('.', $_SERVER['HTTP_HOST'])));

これはあくまで一例です。多言語サイトの URL 構成にはいくつかの考え方があります。 「多地域、多言語のサイト」で Google 検索してヒットする「Search Console ヘルプ」のページを参考にしてください(本 Wiki には URL が書けないので自分で検索してください)。 参考サイトの説明によると URL 構成は4つに大別されます。

以下にそれぞれごとの対応可否をまとめます。

URL 構造対応可否/補足説明
国別example.ie容易に対応可能。国別のドメインをそれぞれ取得可能または既に保持していることが条件。
gTLD を使用したサブドメインde.example.com容易に対応可能。サブドメインの設定が可能であることが条件。
gTLD を使用したサブディレクトリexample.com/de/容易に対応可能。PukiWiki 本体を1つに集約するには index.php を各ディレクトリに配置して PukiWiki 本体を共有するよう設定で対応するか、Web サーバーの Rewrite 機能で対応するなど多少工夫が必要。
URL パラメータsite.com?loc=de実現困難。ページ内リンク全てに言語指定 URL パラメータを付けるにはかなりの本体改造が必要になる。言語切り替え時のみ指定し Cookie や Session に記録する方法もできるにはできるが別言語のページの URL は分けるのが基本らしいので推奨しない。

LANG 定数によって読み込むデータを動的に設定する。

pukiwiki.ini.php に wiki, diff, backup, cache, attach, counter 等のデータ読み込み場所を設定する各種定数設定があります。

それらの定数設定に LANG を組み込みます。以下、設定事例です。

// You may hide these directories (from web browsers)
// by setting DATA_HOME at index.php.

define('DATA_DIR', DATA_HOME . LANG . '/wiki/' ); // Latest wiki texts
define('DIFF_DIR', DATA_HOME . LANG . '/diff/' ); // Latest diffs
define('BACKUP_DIR', DATA_HOME . LANG . '/backup/' ); // Backups
define('CACHE_DIR', DATA_HOME . LANG . '/cache/' ); // Some sort of caches
define('UPLOAD_DIR', DATA_HOME . LANG . '/attach/' ); // Attached files and logs
define('COUNTER_DIR', DATA_HOME . LANG . '/counter/' ); // Counter plugin's counts

ポイントは、読み込みの起点を DATA_HOME . LANG にしているところです。これによって言語設定に応じて読み込まれるデータが自動で切り替わるようになります。

これだけでも大丈夫ですが index.php にある DATA_HOME の設定も少し修正してディレクトリ構成を調整した方が良いかもしれません(任意)。

define('DATA_HOME',	'data/');

以上の設定変更を行った場合のディレクトリ構成は以下の通りになります。

  • PukiWiki 本体
    • data(コンテンツの起点)
      • ja(日本語コンテンツの起点)
      • en(英語コンテンツの起点)

ja と en にはそれぞれ wiki, diff, backup, cache, attach, counter を用意します。 対応言語を増やしたい場合は、ディレクトリを追加します。

補足

以上の設定で国際化サイトの最小構成ができあがりですが、ここからはさらに発展させるためのヒントをいくつか紹介します。

PukiWiki 本体の改造は最小限にすることを念頭に置いて考えています(プラグインの導入は本体には手を加えない単純な機能追加と考えているのでノーカウントです)。

ドメインによる言語判定をローカル環境で動作させる

開発中にローカル環境で国別やサブドメインによる言語判定実装を動作させるには少し工夫が必要になります。

localhost や 127.0.0.1 のアクセスでは正常動作しないので hosts に設定を追加して仮のドメインでアクセスできるようにします。例えば以下のような設定を hosts に追加します。

ja.local.xxx.yyy 127.0.0.1
en.local.xxx.yyy 127.0.0.1

これでローカルのサーバに ja.local.xxx.yyy や en.local.xxx.yyy でアクセスできるようになり、プログラムを変えることなく動作確認ができるようになります。 壊せる環境で色々いじりましょう。

interwiki によるサイト間リンク

interwiki を使うと言語別サイトのページ間リンクを wiki で簡単に書けるようになります。

例えば InterWikiName ページに各言語別サイトへの interwiki 設定を以下のように書き込みます。

※リンク文字列をこの Wiki に書き込めないので意図的に http/// にしています。
-[http///ja.xxx.yyy/index.php?$1 ja] utf8
-[http///en.xxx.yyy/index.php?$1 en] utf8

すると wiki 内で別言語サイトリンクが以下のように書けるようになります。

[[日本語のページへのリンク>ja:PageName]]
[[英語のページへのリンク>en:PageName]]

対応言語を増やす場合は、設定を追加して対応します。

URL の統一

PukiWiki はページ名がそのまま URL になります。言語によってタイトルが変わるということは URL が変わるということです。

言語に関わらず URL を統一するにはページ名とは別にタイトルを設定するプラグインを導入します。 title.inc.php で検索すればページ内でプラグインを呼び出してタイトルの設定ができる実装がいくつか見つかると思います。 好きなのを使ってください。

言語制御系のカスタムプラグインの製作

より柔軟に言語制御を行うためにプラグインを自作する方法があります。

例えば以下のようなことがしたいといった場合はプラグインを作りましょう。

  • 言語切り替えリンク
    • 画面上部のヘッダーに別言語の同一ページへのリンクを張りたいというのはよくある欲求だと思います。
  • 自動 alternate 出力プラグイン
    • 言語別のページがある場合は、その存在を関連付けるために alternate タグをページに埋め込むのが一般的です。人間がそれを見るというよりは SEO 的な意味合いが強いと思います。

作ったプラグインをスキンに埋め込むことで全ページに一括反映させるなどできます。

要件によって欲しい機能というのは変わってくると思うので、ここではこのような各種プラグインを自作するための核となる以下のトピックに焦点を絞って対応方法を紹介します。

  • 対応言語を列挙する方法
  • 現在の言語を判定する方法
  • 指定言語のページ存在判定をする方法

対応言語を列挙する方法

サイトの対応言語を判断する方法は2つ考え方があります。

  • DATA_HOME 配下のディレクトリ名を対応言語として自動判断する方法
  • pukiwiki.ini.php 等で手動定義する方法

最初の方法を実現するには例えば以下のような関数を用意します。

function get_support_languages() {
	$result = array();

	$excludes = array(".", "..");
	$dp = @opendir(DATA_HOME) or die_message(DATA_HOME . ' is not found or not readable.');
	while ($directory = readdir($dp)) {
		if (is_dir(DATA_HOME . $directory) && ! in_array($directory, $excludes)) {
			$result[] = $directory;
		}
	}
	closedir($dp);

	return $result;
}

置き場所は lib/i18n.php 等にして lib/pukiwiki.php に require 文を追加して読み込む等すると良いでしょう。

自動判定は楽ですが、言語に恣意的な順序性を設けることが得意ではありません。

例えば日本語→英語といった順序で画面の表示を統一したい場合は、2番目の方法で手動定義した方が楽でしょう。

$support_languages = array("ja", "en");

対応言語の判定方式が変わかもしれないことを見越して、2番目の方法を採った場合でも関数にしておくことができます。

function get_support_languages() {
	global $support_languages;

	return $support_languages;
}

以上の関数を使って対応言語を取得し、プラグイン内で foreach ループを回します。

function plugin_xxx_inline() {
	// ...

	$support_languages = get_support_languages();
	foreach ($support_languages as $lang) {
		// 言語ごとの何らかの処理
	}

	// ...
}

現在の言語を判定する方法

現在表示されているページの言語は LANG 定数で判断できます。

現在表示中の言語に対して特別な処理を行いたい場合は、対応言語のループ中に判断を加えます。

例えば現在表示中の言語を強調表示したり、処理対象から除外したりなどができます。

実装を以下に例示します。

function plugin_xxx_inline() {
	// ...

	$support_languages = get_support_languages();
	foreach ($support_languages as $lang) {
		if ($lang === LANG) {
			// 現在表示中の言語に対する処理
		} else {
			// それ以外の言語に対する処理
		}
	}

	// ...
}

指定言語のページ存在判定をする方法

ページの存在判定をするには、ディレクトリ構成およびファイルの配置が想定通りの設定になっていることが前提となります。

今回は wiki ファイルの配置場所である DATA_DIR の設定が以下の通りになっていることを前提とします。

define('DATA_DIR', DATA_HOME . LANG . '/wiki/' );

言語毎のページの存在判定は、言語毎のディレクトリにファイルが存在するかどうかの判断によって行います。 PukiWiki 標準の is_page / get_filename を真似して国際化対応の is_page_i18n / get_filename_i18n を以下の通り定義します。

function is_page_i18n($page, $lang) {
	return file_exists(get_filename_i18n($page, $lang));
}

function get_filename_i18n($page, $lang) {
	return DATA_HOME . $lang . '/wiki/' . encode($page) . '.txt';
}

以上の関数を使えば指定言語のページの存在判定が簡単にできます。

  • これは大作ですね。多言語コンテンツについてここまで考えられているのは見たことがありません。言語選択/決定の方法も複数提示してあるので状況によって選べますね。すごい -- umorigu 2017-06-06 (火) 02:12:45
  • PukiWiki/国際化にあるようなページの命名規則でやっていたのですが、最近、発想の大転換があって現状の標準のPukiWikiの設定をちょっと工夫するだけでやりたいことの大部分が実現できると気付いたんです。書き始めたら色々出てきたので、せっかくなので周辺の情報も整理してみました。 -- toydev? 2017-06-06 (火) 23:16:39


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2017-06-06 (火) 23:19:23
Site admin: PukiWiki Development Team

PukiWiki 1.5.1+ © 2001-2016 PukiWiki Development Team. Powered by PHP 5.6.30-0+deb8u1. HTML convert time: 0.369 sec.

OSDN