ネゴシエーションによるApacheの言語サポート

Apacheのhttpd.confファイルを少しご覧になったことがある方なら、最初の方の数行にAddLanguage de .de およびAddLanguage fr .fr と 記載されているのにお気付きになったかもしれません。この記事では、David Seagerが、これらが何であるか、何をするのか、また、どのように使うのかについて説明します。

David Seager, CICS/390 Development, IBM Hursley

David Seagerは、2年以上に渡ってLinuxおよびWebベースのアプリケーションに関する仕事をしています。



2001年 2月 01日

Apache言語機能

Apacheの最新バージョン (バージョン1.2以降) は、HTTP仕様の「コンテンツ・ネゴシエーション」 をサポートします。これにより、Webブラウザーは、ユーザーが該当のWebサーバーと交信して、Webページで表示させたいコンテンツ のタイプに関する情報を、Webサーバーに送信することができます。この情報は、ブラウザーがサポートしているイメージのフォーマットから、ユーザーが見たい言語に至るまで、多岐に渡ります。これには、AddLanguage ディレクティブが関係してきます。

Apacheには、この言語設定を使用して、さまざまなバージョンのHTMLページを、さまざまなページ・エレメント (国旗のグラフィックなど)、リンク、またはWebデザイナーが好むデザインとともに、ユーザーが希望する言語で表示する機能があります。もちろん、これをすべて可能にするには、サーバー・サイドで若干の作業が必要になります。

一般的に、サーバー上のWebページは、.htmlという拡張子の付いたファイルです。サイトのビジターが ファイルを指定すると、そのファイルがビジターに提示されます。これ自体には、何も目新しい点はありません が、AddLanguage ディレクティブは、そのようなファイルの特定の言語バージョンが、指定された追加の拡張子付きで表示されるように指定します。たとえば、AddLanguage fr .fr は、.fr拡張子が付いたフランス語バージョンのファイルが あることを示します。したがって、フランス語の読者用にはindex.html.fr、ドイツ語の読者用には index.html.deといったファイルを用意することができます。キーワード "fr" はフランス語、"de" はドイツ語 というように指定します。言語キーワードのリストのリンクについては、参考文献を参照してください。

これを行うのは、簡単です。通常、httpd.confにすでにAddLanguage 行があります。無い場合には、次のようなフォーマットで指定します。最初のパラメーターに言語キーワード (Webブラウザーによって送信されるキーワードと同じ) を、2番目のパラメーターには、Apacheがその特定の言語用の ファイルで検索すべき拡張子を指定します。したがって、.fr拡張子が付いたフランス語のファイルを 選ぶ場合には、次のように指定します。

AddLanguage fr .fr

ドイツ語、英語、イタリア語などの場合も同様に指定します。

AddLanguage it .it
AddLanguage de .de
AddLanguage en .en
AddLanguage da .da
AddLanguage el .el

この機能を使用したいディレクトリーに対するディレクティブにおいて、MultiViews という オプションを明示的に追加する必要があります。MultiViews は、基本的に、ファイルが 要求された時に、これらの特別の言語固有ファイルを探すようにApacheに命令するもので、必ず指定する 必要があります (Options All に含まれていないため)。私のルート・ディレクトリーの 場合、httpd.confに次のように指定しています。

<Directory /home/httpd/html>
Options MultiViews
</Directory>

最終ステップは、実際の言語固有ファイルを作成することです。私は、簡単なテストを行うために、明らかにそれとわかるファイルを数個作成し、それをルート・ディレクトリーに入れました。

MultiViewsオプションを使用すると、Apacheは、要求されたファイルが無い場合に、言語に基づいた 突き合わせしか行いません。test.htmlファイルがあると、ビジターがどの言語を指定しても、常にそのファイルが提示されます !

-----test.html.fr------
French
-----------------------
-----test.html.en------
English
-----------------------
-----test.html.de------
German
-----------------------

クライアント・サイドで必要なことは、ビジターの言語設定を指定することだけです。Netscapeでこれを行う場合には、Edit--> Preferences と選択し、Navigator --> Languages タブを選択し、Addボタンをクリックして、言語を追加します。"French [fr]"、"English [en]"、"German [de]" を追加して、フランス語、ドイツ語、英語の順に配列します。

これをテストするには、Webブラウザーを使用して、"test.html" というドキュメントを、それが 入っているディレクトリーで要求します。私の場合はルート・ディレクトリーに入れたので、http://myserver/test.htmlと指定します。そうすると、Apacheは、フランス語のドキュメントを 提示するはずです。Netscapeでの言語の順序を入れ替えて、Apacheがドイツ語または英語バージョンの ファイルを表示するように設定することもできます。

ビジターが言語指定していない場合、または見たことが無い、あるいはまだ対応していない言語を指定している場合、Apacheのドキュメントには記述されていませんが、test.html. というファイル名 (末尾にピリオドが付いており、言語識別が無いもの) を 指定すると、Apacheは、一致する言語が見付からない場合に、そのファイルを提示するようです。(私は、これをApache 1.3.9でテストしたので、ご使用になっているバージョンによって異なる可能性 があります。)

それでは、これは、実際どのように動作しているのでしょうか ? Webブラウザーで言語設定 を指定すると、Webブラウザーは、要求が出されるときにWebブラウザーがWebサーバーに送信するHTTPヘッダー に、指定されている言語を使用します。このヘッダーはAccept_Language で、通常は、ユーザーが指定する言語キーワード のリスト (言語設定が降順に指定されたもの) です。よって、私のWebブラウザーの場合は、ヘッダー部に、

より正確に言うと、コンテンツ・ネゴシエーション・モジュール (mod_negotiation -- これは、デフォルトでコンパイルされることがよくあります) が作動しています。動的共用オブジェクト・サポートを使用している場合には、httpd.confに、以下のモジュールをロードするための行が数行あることにお気付きになるでしょう。
LoadModule negotiation_module modules/mod_negotiation.soAddModule mod_negotiation.c (これらの行は、LinuxバージョンのApache 1.3のものです。)

Accept-Language: fr de en

と指定して送信します。

MultiViews オプションが指定されており、要求されたファイルが無い場合、Apacheは、言語固有のファイルを探し、該当するファイルを提示します。

タイプ・マップ

全く違う名前の2つの異なる言語ファイルが必要な場合には、ユーザーの設定 に基づいて再度選択されます。これは、「タイプ・マップ」と呼ばれる mod_negotiation の もう1つの機能です。これは、ある特定のファイル名について、異なるドキュメント名の選択項目を明示的に指定することが できるテキスト・ファイルです。

タイプ・マップ・ファイルには、Apacheが識別できる特定の拡張子があります。httpd.confの

AddHandler type-map var

という行は、.varという拡張子のファイルがタイプ・マップとして扱われることを指定します。もちろん、好きな拡張子を自由に選択できます。また、この行は、サーバーにおけるタイプ・マップ処理 を可能にします。

タイプ・マップ・ファイルは、複数のファイルを指定し、複数行に分割されます。各行には、キーワード名、コロン、空白および値が指定され、各ファイルの記述はブランク行で 分離されます。使用するキーワードは、ファイルを指定する "URI"、ファイルのMIMEタイプを 指定する "Content-Type"、およびその言語を指定する "Content-Language" です。たとえば、タイプ・マップ・ファイルの例 (menu.varと呼びます) のenglish_menu.html (英語) とfrench_menu.html (フランス語) という2つのファイルがある場合には、次のようにコーディングします。

------menu.var------
URI: english_menu.html
Content-Type: text/html
Content-Language: en
URI: french_menu.html
Content-Type: text/html
Content-Language: fr
--------------------

さらに、例を示します。

---english_menu.html---
English menu
-----------------------
---french_menu.html----
French menu
-----------------------

これらのファイルをすべてルート・ディレクトリーに入れて、http://myserver/menu.var (私のサーバー のセットアップの場合) を要求すると、ブラウザーでどちらの言語が優先する設定に なっていたかによって、フランス語または英語のいずれかのメニューが表示されます。


比較

MultiViewsオプションを使用すると、Apacheは、Content-Type およびLanguage-Type を 判別するためのMIMEタイプおよび言語拡張子を使用して、要求されたものに一致するファイル のタイプ・マップをディレクトリーに作成し、それから、前述したようにマッチングを行います。MultiViews と比較した際のタイプ・マップ の利点は、タイプ・マップを作成するためのこの余分なプロセスが不要である点です。欠点は、複数の言語リソースごとにタイプ・マップをコーディングしなければならないことです !


サーバー・サイド・インクルード (SSI)

これまでは、Webページ全体をさまざまな言語で表示することについてお話してきました。しかし、あるページの一部だけを言語依存にしたい (たとえば、国旗のロゴや ウェルカム・メッセージをビジターの言語で表示するなど) 場合はどうでしょう ? 嬉しいことに、コンテンツ・ネゴシエーションは、さまざまなApacheの処理状態で作動します。そのうち の1つは、サーバーによって構文解析されるhtmlファイルです。

SSIは、Apacheの優れた機能の1つです。HTMLの1ビットは多数の異なるページに組み込むことが でき (たとえば、ナビゲーター、タイトル・バナー、ページ・フッターなど)、単一のファイルにしか 存在しないので、サイト・メインテナンスが簡単に行えます。このような「HTMLフラグメント」は、さまざまな言語にも依存することができ、Apacheは、コンテンツ・ネゴシエーションを使用して、正しいものを 組み込みます。

サーバーによって構文解析されるHTMLファイルは、httpd.confで以下の行を指定することにより、使用できます。

AddType text/html .shtml
AddHandler server-parsed .shtml

SSIを使用できるようにしたら、ディレクトリー・ディレクティブで +Includesオプションを使用します。

<Directory /home/httpd/html>
Options MultiViews +Includes
</Directory>

組み込みモジュール (mod_include) は、サーバー・サイドの構文解析をすべて行います。mod_include モジュール については、httpd.confで以下を見付けて、ApacheマニュアルでSSIについて詳しくお読みください。(参考文献を参照してください。)

LoadModule includes_module modules/mod_include.so
AddModule mod_include.c

私は、例として、ウェルカム・メッセージが含まれているホーム・ページを作成しました。

----home.shtml-----
<h2>My Home Page</h2>
<!--#include virtual="welcome" -->
-------------------

さらに、2つの異なるバージョンのメッセージも組み込みました。

----welcome.en-----
Welcome!
-------------------
----welcome.fr-----
Bonjour!
-------------------

これで、http://myserver/home.htmlをブラウザーにロードすると、"My Home Page" という タイトル・ページがすべての言語で表示され、カスタマイズされたウェルカム・メッセージが表示されます。


パーソナル・ホーム・ページ (PHP)

私の好きなサーバー・サイド・スクリプト言語のPHPが、この種の言語依存性に対するサポートを行っていたら、なんと素晴らしいことでしょう (参考文献を参照してください)。幸いにも、PHPは優れた言語です。PHPには、Apacheサブ要求を実行して、SSIと同じように仮想組み込みを行う機能があります。virtual() 関数により、Apacheは、<!--#include virtual="" --> と 同じことを行えるので、ユーザーによって指定された言語設定に基づいた ドキュメントを選択することができます。

PHPを使用した場合、前述のホーム・ページは次のようになります。

-----home.php3------
<h2>My Home Page</h2>
<?php
  virtual("welcome");
?>
--------------------

これは、仮想組み込み機能にアクセスする他のあらゆるサーバー・サイド・スクリプト言語にも 適用できます。


自分で作成する場合の方法

表示されるページ内容を更に制御したい場合、あるいは、ビジターの言語に応じて異なる サーバー・サイド・コードを使用したい場合には、ユーザー自身のスクリプトで、mod_negotiation が 行っていることと同じことができます。

以下にPHPを使用した例をあげます。get_language 関数は、Accept_Language ヘッダー の内容を保持している $HTTP_ACCEPT_LANGUAGE 変数を見て、それを最優先のものを最初に して、希望する言語の配列に分割します。

$language_pages 配列は連想配列で、呼び出し元に戻されるストリングに言語キーワードを関連付けます。関数は、それぞれの言語キーワード設定ごとに、 $language_pages をチェックして、キーの一致を検索します。一致するものが見付かったら、値が戻されます。

ビジターが言語設定を指定しなかった場合、関数は、単にデフォルトの言語を戻し、選択された言語が見付からない場合、関数は、別のデフォルト値を戻します (この例では、両方とも "english" になります)。

<?php
function get_language()
{
  global $HTTP_ACCEPT_LANGUAGE;
  $language_pages = array(
                      "en"=>"english",
                      "fr"=>"french"
                    );
  $language_default = "english";
  $language_nofound = "english";
  // get preferred languages in the "Accept-Language" header
  if($HTTP_ACCEPT_LANGUAGE == "")
  {
    // no preference set
    return $language_default;
  }
  // form an array of preferred languages
  $accept_language = str_replace(" ", "", $HTTP_ACCEPT_LANGUAGE);
  $languages = explode(",", $accept_language);
  // check for a recognised language
  for($i = 0; $i< sizeof($languages); $i++)
  {
    if($language_pages[$languages[$i]] != "")
    {
      // found a preferred language
      return $language_pages[$languages[$i]];
    }
  }
  return $language_nofound;
}
echo get_language();
?>

この例では、ビジターの言語設定と一致した場合に、english およびfrench という ストリングを戻す、2つの言語 -- 英語とフランス語 (enfr) を持つ連想配列を コーディングしました。この関数を更に複雑な使い方で使用すると、言語に基づいて組み込むイメージの名前またはPHP関数の名前のHTMLタグを判別することもできるでしょう。この例では、一致する言語の名前をプリント・アウトしました。


結論

おわかりのように、Apacheは、Webページをビジター自身の言語にカスタマイズし、より個人向けの、各国の言語に合わせた表示を可能にする強力なメカニズムです。httpd.confを少し変更するだけで、お客様のWebサイトでも同じようなことを始められます !

参考文献

  • RFC 1766 には、言語キーワードの詳細なリストが記載されています。
  • mod_include モジュールについては、 Apache manual pages のSSIの箇所をお読みください。

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Web development
ArticleID=294805
ArticleTitle=ネゴシエーションによるApacheの言語サポート
publish-date=02012001