PukiWiki を使った国際化サイトの作り方のヒントを事例を踏まえて紹介します。
by toydev
誰でも書き込みができるいわゆる Wiki としてではなく、単純な CMS として個人サイトで PukiWiki を使っている事例を元にしています。
書き込みをする人は管理者一人だけであり、全体のコントロールが容易であることが前提です。Wiki として不特定多数が自由に書き込める状況で採用した場合に何が起こるかは予測の範囲に入っていません。
必要な設定変更は2つだけです。
それぞれについて説明します。
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 は分けるのが基本らしいので推奨しない。 |
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/');
以上の設定変更を行った場合のディレクトリ構成は以下の通りになります。
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 を使うと言語別サイトのページ間リンクを 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]]
対応言語を増やす場合は、設定を追加して対応します。
PukiWiki はページ名がそのまま URL になります。言語によってタイトルが変わるということは URL が変わるということです。
言語に関わらず URL を統一するにはページ名とは別にタイトルを設定するプラグインを導入します。 title.inc.php で検索すればページ内でプラグインを呼び出してタイトルの設定ができる実装がいくつか見つかると思います。 好きなのを使ってください。
より柔軟に言語制御を行うためにプラグインを自作する方法があります。
例えば以下のようなことがしたいといった場合はプラグインを作りましょう。
作ったプラグインをスキンに埋め込むことで全ページに一括反映させるなどできます。
要件によって欲しい機能というのは変わってくると思うので、ここではこのような各種プラグインを自作するための核となる以下のトピックに焦点を絞って対応方法を紹介します。
サイトの対応言語を判断する方法は2つ考え方があります。
最初の方法を実現するには例えば以下のような関数を用意します。
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'; }
以上の関数を使えば指定言語のページの存在判定が簡単にできます。