PHP アプリケーションを国際化する

誰もが利用できる PHP アプリケーションにするためのツールと戦略を学ぶ

アプリケーションのローカライズは、事前に計画して行われる場合もあれば、あわてて後から行う羽目になる場合もあります。gettext や XML、XSLT、そしてデザイン・パターンなどによる方法やツールを学び、成熟した製品を後からローカライズする場合、あるいは最初からローカライズを計画する場合に役立てましょう。

Robert Bradley (robert.bradley@gmail.com), Consultant, ALDION Consulting Pte Ltd

Robert Bradley はソフトウェア・エンジニアリングに関して 20 年以上の経験を持ち、半分隠退生活を送りながら、執筆活動やコンサルティングを行っています。彼は昔覚えたドイツ語を翻訳のサンプルに使いました。



2007年 1月 16日

アプリケーションを見積もる

ローカライズするための要件は、例えば「このアプリケーションをドイツ用にする」のように曖昧なものかもしれません。しかし、要件が詳細に規定されているように思える場合であっても、その製品のマネージャーが考慮していなかった事項が見つかることもあります。

例えば、リスト 1 に示す、必要最低限の Yahoo! の RSS ニュース・リーダー・アプリケーションを見てださい。このページが最初に呼び出されると、デフォルトのヘッドライン・リストが表示され、そこにフォーム・フィールドがあります。ユーザーは選んだニュースのカテゴリーをそこに入力し、このページを再送信します。そうするとアプリケーションは入力されたカテゴリーを検証し、カテゴリーが有効でなければエラー・メッセージを表示し、有効であれば、要求されたカテゴリーのヘッドラインを表示します。

リスト 1. Yahoo! の RSS ニュース
<?php

require_once "XML/RSS.php";

# Normalize and validate user input

$newstype = strtolower(isset($_POST['newstype']) ? $_POST['newstype'] : "tech");
$error = null;
switch($newstype) {
  case 'world':
  case 'tech':
	break;
  default:
	$error = 'Invalid news type.';
	break;
}

?>

<html>
<head>
<title>RSS Feed from Yahoo News</title>
</head>
<body>
<h1>RSS Feed from Yahoo News</h1>

<p>
Welcome to the Yahoo RSS news reader.  To view headlines for different kinds of news
enter the news type in the text box below and then submit the form.  Valid news types
are 'tech' and 'world'.
</p>
<p>
<form method = "POST">

<?php
  if (isset($error)) {
	echo '<br/><font color = "red">' . $error . '</font><br/>';
  }
?>

<input type = "text" name = "newstype" value = "<?php echo $newstype ?>" />
<br>
<input type = "submit">
</form>
</p>
  
<?php
  $url = "http://rss.news.yahoo.com/rss/" . $newstype;
  $rss = new XML_RSS($url);
  $rss->parse();
  echo "<ul>\n";
  foreach ($rss->getItems() as $item) {
	echo "<li><a href=\"" . $item['link'] . "\">" . $item['title'] . "</a></li>\n";
  }
  echo "</ul>\n";
?>
  
</body>
</html>

このアプリケーションは非常に単純ですが、ローカライズに関わる多くの問題を提示しています。またここには、スクリプト言語によるいくつかの長所と短所も見られます。

製品を大急ぎで出荷してしまうのも 1 つの手段ですが、それには代償が伴います。つまり、新機能を追加することによるページの管理やページの拡張に関して考慮しておかないと、UI (user interface)、ビジネス・ロジック、および構成が (あるいはそれが欠けた状態が) ごちゃ混ぜになったものになってしまいます。

このページをドイツ語用にローカライズしようとすると (他の言語の場合もおそらく同様です)、次のようにいくつかの障害があることがわかります。

  • さまざまなアプリケーション層を分離するために、コードをリファクターする必要があります。
  • UI テキスト (ヘッドラインやコンテンツ、エラー・メッセージなど) を抽出し、翻訳する必要があります。
  • フォーム・コントロール (Submit ボタンなど) をローカライズする必要があります。
  • アプリケーションには、対象ロケールを定義する方法が必要です。
  • ユーザー入力への要件と検証がロケール毎に異なります。
  • 対象ロケールと構文は国ごとに異なるため、ロケール依存のビジネス・ルール (例えば Yahoo! RSS フィード用の URL など) を考慮する必要があります。
  • アプリケーション・ドメインの動作の構成とコントロールを、ロケールごとにサポートするフレームワークが一層重要になります。

これらすべてを実現するための作業は、オリジナル・アプリケーションのコストに匹敵、あるいはそれを上回るかもしれません。これは関係者にとって頭の痛い問題です。結果的に皆さんのチームは、こうした困難への対応を、アプリケーションが完成する前、あるいは後に行う必要があります。


ローカライズの用語

皆さんがプロジェクトで翻訳者とやり取りする際には、彼らとの会話に登場しがちないくつかの用語を理解してお必要があります。表 1 は、言語の専門家や翻訳者が使う一般的な用語です。

表 1. ローカライズのための用語
用語意味
ロケール言語と、国または地域の組み合わせ (例えば en_US や en_GB、de_DE など)
国際化 (I18N: Internationalization)ローカライズすべきアプリケーションの計画、設計、準備
ローカライズ (L10N: Localization)対象とするロケールのための、アプリケーションの UI の特定と翻訳 (T9N: translation)
外部化 (ストリング抽出)プログラム・ストリングを翻訳用に抽出するプロセス

改造で対応するローカライズ

リスト 2 は、RSS アプリケーションをリファクタリングし、ローカライズをサポートするように改造した様子を示しています。機能ロジックとローカライズ・フレームワークは、ハンドラー・クラスの中に抽象化されています。メインのコード行に残っているのは、ページ・ハンドラー・オブジェクトの作成と HTML テンプレート、そして HTML テンプレートの動的部分にデータを入れるための、ハンドラーの accessor メソッドへのコールのみです。

リスト 2. ローカライズされた RSS ニュース
<?php
# news2.php
require_once "RSSHandler.php";
$handler = new RSSHandler;
?>

<html>
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <title><?php echo $handler->getTitle() ?></title>
  </head>
  <body>
    <h1><?php echo $handler->getTitle() ?></h1>
    <p>
      <?php echo $handler->getGreeting() ?>
    </p>
    <?php $handler->showerror() ?>
    <form method = "POST">
      <input type = "text" name = "newstype" 
        value = "<?php echo $handler->getNewstype() ?>" />
      <br/>
      <input type = "submit" 
        value="<?php echo $handler->getSubmitbutton() ?>" />
    </form>
    <?php $handler->showHeadlines() ?>
  </body>
</html>

リファクタリングの利点は、おそらくプログラマーにとってコードの管理が容易になることです。とはいえ、言語コンテキストがなくなり、また HTML の大部分が PHP コードの中に埋め込まれたままの状態で UI が管理しやすいかどうかは、議論の余地があります。

PHP プログラマーは、こうした変更に関して Web 開発者を信頼するでしょうか。バックエンドの開発者を用意し、マイナーな UI 変更の要求に対応するとしたら、コストはどのくらいかかるのでしょう。後ほど、アプリケーション層を適切に分離する上で XSLT (Extensible Stylesheet Language Transformation) が役立つことを示します。

コンストラクター

では、ページをどう改造してローカライズしたかを見るために、ハンドラー・クラスのためのコンストラクター (リスト 3) から始めることにしましょう。ページ・ハンドラーがインスタンス化されると、コンストラクターは適切なロケールを判断し、そのロケール用の構成設定を取得し、ユーザー入力があればそれを検証し、それまで静的であったコンテンツをユーザーの現在のロケールに基づいて計算し、そしてユーザー入力があればそれを検証します。 (ソースコードについては「ダウンロード」を参照してください。)

リスト 3. RSSHandler.php
  public function __construct() {

    # set up locale
    putenv("LANG=de_DE");       # for the configuration
    setlocale(LC_ALL, 'de_DE');   # for gettext

    # Get locale-dependent configuration
    $this->conf = new RSSConfig;
    $this->configdecorator = new Configdecorator($this->conf);

    # set up the text extraction context
    bindtextdomain($this->conf->getTextdomainmessage(),  
      $this->conf->getTextdomainpath());
    textdomain($this->conf->getTextdomainmessage());
    
    # Extract the strings for translation.
    $errormsg = gettext("News type is not valid.");
    $this->title = gettext("Yahoo RSS News");
    $this->submitbutton = gettext("Get the news.");
    $lgreeting = 
      gettext("Welcome to the Yahoo RSS news reader. ") . " " .
      gettext("Enter a news type, then submit the form.") . " " .
      gettext ("Valid news types are: %s.");
    $decoratedtypes = $this->configdecorator->getNewsTypes();
    $this->greeting = sprintf($lgreeting, $decoratedtypes);
    
    # Normalize and validate 
    $this->newstype = $this->normalize();
    $this->error = $this->validate() ? '' : $errormsg;
  }

この例では、単純にするためにロケールを de_DE にハードコード化しています。現実のシナリオでは、ビジネス要件に基づいてロケールを設定する必要があります。適切なロケールを判断するための一般的な方法として、リクエスト URL (例えば、www.ebay.de や amazon.fr など) を調べる方法と、単純にユーザーに尋ね、ユーザーのブラウザーのプリファレンス・クッキーを設定する方法という 2 つがあります。

構成パラメーターを取得する

ロケールが判断できたら、ハンドラーはドイツ用の構成パラメーターを取得します。この例の構成では、PEAR パッケージ (Config.php) と XML 構成ファイル (RSSConfig.xml)、アプリケーション・ドメイン専用のラッパー (RSSConfig.php)、そして一部の構成パラメーターに HTML マークアップを追加するための単純なデコレーター・クラス (Configdecorator.php) を使っています。

リスト 4 に示す構成ファイルは、その情報を XML フォーマットで保存します。このファイルは、ストリングを抽出するためのコンテキスト (//conf/textdomain)、つまりロケールに依存するコンポーネントとメッセージ・ファイルの名前を指定します。

注意: サンプルをダウンロードして実行する際には、抽出され翻訳されたストリングへのパスを、必ず環境に合わせて変更します。

また構成ファイルはアプリケーションに対して、正しい Yahoo! ニュースフィード URL の構築方法 (//conf/de_DE/baseurl) や、ユーザーが選択したニュースフィード・タイプの検証方法 (//conf/de_DE/newtypes)、ユーザーが何も選択しなかった場合にどのタイプのニュースをデフォルトにするか、なども指定します。

リスト 4. Configuration.xml
<?xml version="1.0" encoding="UTF-8"?>
<conf>
    <textdomain>
    	<path>/home/bbradley/Sites</path>
	<messagefile>messages</messagefile>
    </textdomain>
    <en_US>
        <baseurl>http://rss.news.yahoo.com/rss/</baseurl>
        <newstypes>
            <type>
                <default>true</default>
                <name>tech</name>
                <url>tech</url>
                </type>
            <type>
                <default/>
                <name>world</name>
                <url>world</url>
                </type>
        </newstypes>
    </en_US>
    <de_DE>
        <baseurl>http://de.news.yahoo.com/</baseurl>
        <newstypes>
            <type>
                <default>true</default>
                <name>Ausland</name>
                <url>politik/ausland.html.xml</url>
                </type>
            <type>
                <name>Technik</name>
                <url>technik/index.html.xml</url>
                </type>
        </newstypes>
    </de_DE>
</conf>

「デフォルト」ロケールを追加すると、より確実な構成にすることができます。そうすれば、もしアプリケーションが無効なロケールを描画しようとする際に、必ず何らかの適切なアプリケーション動作が保証されることになります。また構成を拡張することによって、何かと協調動作をさせたり、ユーザー特権に基づいてアプリケーションを制限したりするなど、他のアプリケーション様式に対応するようにもできます。

ハンドラー・オブジェクトの残りの大半では、各ロケール用にページのテキスト部分を適切に抽出しています。また public の accessor メソッドを提供し、こうした翻訳されたテキスト部分を HTML テンプレートで利用できるようにしています。

gettext 抽出フレームワーク

このアプリケーションは、翻訳されたストリングを、gettext というオープン・ソースのストリング抽出フレームワークを使って抽出しています。このフレームワークには、次のようにいくつかの利点があります。

  • 無料です。
  • さまざまなプラットフォームで実行することができます。
  • PHP を含め、多くのプログラミング言語で動作します。
  • 特に改造作業に適しています。

gettext を使うには、

  1. サポートする必要のあるロケールすべてに対してディレクトリー構造を作成します。
  2. ストリングを、特別な関数 gettext() の引数の中に移動することで、そのストリングをマークアップします。
  3. xgettext コマンド・ライン・ユーティリティーを実行し、ストリングをメッセージ・ファイルの中に抽出します。
  4. できあがったメセージ・ファイルを各ロケール専用のディレクトリーにコピーします。
  5. メッセージ・ファイルのローカル版を編集し、テキストを翻訳します。
  6. msgfmt コマンド・ライン・ユーティリティーを実行し、(実行時に使用される) ローカライズされたメッセージ・データベースを作成します。

重要な点として、gettext() 関数が、ローカライズされたテキストを実行時に取得する、という明白な目的を果たすことに注目してください。同じく重要な点として、この関数はテキスト抽出用のマーカーにもなっています。xgettext ユーティリティーは、この関数でマークされるストリングを探します。

リスト 5 は、アプリケーションを構成する際に定義したディレクトリー構造を含め、サンプル・アプリケーションのすべてのソフトウェア・コンポーネントを示しています。どの gettext 実装にも、これと似たディレクトリー構造が必要です。デフォルト・ロケール用にはディレクトリー・ツリーやメッセージ・データベースを作成する必要はありません。デフォルト・ロケール用のストリングは、既にコードの中に埋め込まれています。しかし、gettext フレームワーク用のこうしたファイルへのフル・パスを正しく指定するためには、RSSConfig.xml ファイルを編集する必要があります。

リスト 5. ディレクトリー構造
ConfigDecorator.php -- Decorator class
de_DE -- Directory for Germany
	LC_MESSAGES -- Messages sub-directory
		messages.mo -- Compiled messages database
		messages.po -- Translated messages
messages.po -- Generated by xgettext
news2.php -- Main application / HTML template
RSSConfig.php -- Application configuration class
RSSConfig.xml -- Application configuration file
RSSHandler.php -- HTTP request handler / business logic

メッセージ・ファイルを翻訳する

ドイツ語のメッセージ・ファイルの中で、翻訳者が提供すべき部分は太字でマーキングされています。つまり翻訳者は空白を埋める必要があります。翻訳者が最初にメッセージ・ファイルを開くと、こうした部分は空であり、翻訳者は自分が使用する文字エンコーディング (この場合は Latin-1) と、翻訳とを指定する必要があります。メッセージ ID (msgid) は、gettext() 関数へのコールで抽出用としてマーキングされたオリジナル・テキストです。メッセージ・ストリング (msgstr) は、対象言語で表示されるとおりのストリングです。リスト 6 は、ユーザーが不正なニュース・タイプを指定した場合のエラー・メッセージの翻訳を示しています。

リスト 6. ドイツ語のメッセージ・ファイル、messages.po.de
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2006-11-05 11:05-0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ISO-8859-1\n"
"Content-Transfer-Encoding: 8bit\n"

#: RSSHandler.php:31
msgid "News type is not valid."
msgstr "Die Nachrichtkategorie ist falsch."

もし、抽出されたストリングのうちのどれかのテキストが変更された場合には、次回メッセージ・ファイルが生成される際に新しいメッセージ ID が作成されます。ストリングが追加、あるいは変更される度に、メッセージ・ファイルを再生成する必要があります。そうしないと、対象ロケールでは新しいテキストが翻訳されない状態で表示されます。

実動環境では、通常はローカライズ・チームが、(ソースコードを準備する以外の) こうしたすべての作業を行います。だからといって、開発者が言語の問題にまったく無関心でよいことにはなりません。アプリケーションをローカライズする際には、次のような問題に注意する必要があります。

  • 機能情報をストリングの中に埋め込まない。
  • 文をいくつものストリングに分割せず、printf トークンを使ってフル・センテンスで動的コンテンツを扱う。文の中の単語の順序は言語によって異なることを念頭に置き、翻訳者が単語の順序を変えられなくなるようなことをすべきではありません。もしストリングが複数の動的要素を含んでいる場合には、msgfmt が拡張マークアップ構文をサポートしており、これを使うことでストリング中の各動的要素の位置を指定することができます。要素の順序は、翻訳作業中にいくらでも変わる可能性があります。位置構文の詳細を学ぶためには、gettext のオンライン・マニュアルを見てください (「参考文献」を参照)。
  • ストリングに十分なコンテキストを持たせ、意味のあるストリングにする。翻訳者は、実行しているアプリケーションではなく、ストリングしか見ないことを忘れてはいけません。

注意: ソフトウェアをローカライズする際の言語学的な側面に関するヒントについては、「参考文献」を参照してください。

新しいテキストを追加する場合、あるいは既存のテキストの言葉を言い換える場合には、ローカライズ・チームは他の gettext ユーティリティーを使うことで、新しい、あるいは変更されたストリングを既存のメッセージ・ファイルにマージさせることができ、それによって再翻訳の必要がなくなります。


ローカライズのための設計

これまでに説明した方法によるローカライズでも、多くの場合は十分なはずです。しかしもっと大がかりなものになると、デザイン・パターンを使ったアプリケーション設計を検討した方が得策です。最も広く使われているパターンは、MVC (Model-View-Controller) です。このパターンでは、プレゼンテーション、ドメイン、データ・アクセスという階層でアプリケーションを扱おうとします。もう 1 つ、MVC パターンの良いところは、コントローラーとビューを容易に拡張でき、他のタイプの HTTP リクエストを SOAP サービスとして、あるいは XML API として扱える点です。

RSS MVC パターン

Struts と Ruby on Rails、そして Zend Framework はどれも、この階層化設計という概念を採用しています。MVC による方法に関心のある人は、PHP 用の Zend Framework について調べてみてください。ここでは、サンプル・アプリケーションに必要な追加パッケージの数を減らすために、リスト 7 に示す独自の MVC パターンを作ることにします。

これで、メインのコード行のサイズはさらに小さくなりました。このコードは、HTTP リクエストをサービスするための大部分の作業を委譲するコントローラーとして機能します。またこのコードは、先に説明したものと同じビジネス・ルールを強制するドメイン・オブジェクトを作成し、そのドメインからセッション・データのモデルを取得し、そしてそのモデルをビュー・クラスに渡します。ビュー・クラスはモデルを HTML に変換し、それをクライアントに返送します。

リスト 7. RSS ニュース・コントローラー、news3.php
<?php
# news3.php
require_once "View.php"; 
require_once "RSSDomain.php";

putenv("LANG=de_DE");
$domain = new RSSDomain;
$model = $domain->getModel();
$view = new View($domain->getTemplate(), $model);
echo $view->asHTML();
?>

ビジネス・ルールの動作をコントロールするアプリケーション構成の仕組みは、先ほどと同じです。変わった点は、新しいプレゼンテーション層による、UI の処理方法です。この層は、今度は PHP の HTML テンプレート・サポートを使う代わりに、XSL 変換に依存します。ドメイン・モデルはネストしたオブジェクトの再帰データ構造であり、XML としてシリアライズされます。ビューは XSL テンプレートを使って、セッション・データの XML 表現を、クライアントのブラウザーに返送されるローカライズされた HTML に変換します。

プレゼンテーション層

プレゼンテーション層のコアとなる XML モデルと XSL テンプレートを、リスト 8 に示します。このモデルには、ニュース・タイプなどの構成情報、特にこうした選択をユーザーにどう表示するかに関する構成情報が含まれています (//rss/newstypes/displaytypes)。またこのモデルは、ユーザーが選択したニュース・タイプ (//rss/userinput/newstype) と、取得されるニュースのヘッドラインと URL (//rss/headlinelist/headline) も返します。もしユーザーが選択したニュース・タイプが無効だった場合には、モデルはヘッドラインの代わりにエラー・コードを返します。XSL テンプレートは、返されるデータ・モデルの一部にアクセスし、クライアントのブラウザーに表示される HTML を作成します。

リスト 8. XML モデルと XSL テンプレート (RSSView.xsl) のサンプル
 <rss>
 	<newstypes>
		<displaytypes>Ausland, Technik</displaytypes>
		<typelist>
			<type>Technik</type>
			<type>Ausland</type>
		</typelist>
	</newstypes>
	<userinput>
		<newstype>Ausland</newstype>
	</userinput>
	<headlinelist>
		<headline>
		<hlink>http://de.news.yahoo.com/01112006/12/guatemala.html</hlink>
		<htitle>Guatemala und Venezuela halten Besprechungen</htitle>
		</headline>
		<headline>
		<hlink>http://de.news.yahoo.com/01112006/12/mandat.html</hlink>
		<htitle>Mandat einer Regierung in Afrika</htitle>
		</headline>
	</headlinelist>
</rss> 

---------------------------------------------------------------

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:variable name="pagetitle">Yahoo Schlagzeilen</xsl:variable>
<xsl:variable name="submitbutton">Hol Schlagzeilen</xsl:variable>
<xsl:variable name="displaytypes">
<xsl:value-of select="/rss/newstypes/displaytypes"/>
</xsl:variable>
<xsl:variable name="newstype">
<xsl:value-of select="/rss/userinput/newstype"/>
</xsl:variable>

<xsl:template match="/">
<html>
	<head>
		<meta content="text/html; charset=utf-8" http-equiv="Content-Type"/>
		<title>
			<xsl:value-of select="$pagetitle"/>
		</title>
	</head>
	<body>
		<h1><xsl:value-of select="$pagetitle"/></h1>
		<p>
		Willkommen! Um den Yahoo Nachrichtleser zu gebrauchen, gib einen von den
		folgenden Nachrichttypen ein:  \
		<xsl:value-of select="/rss/newstypes/displaytypes"/>!
		</p>
		<!-- errors  -->
		<xsl:choose>
			<xsl:when test="rss/userinput/error/code">
				<p><b><font color="red">Falscher Typ</font></b></p>
			</xsl:when>
		</xsl:choose>
		<p>
		<form method = "POST">
			<input type = "text" name = "newstype" value = "{$newstype}" />
			<br/>
			<input type = "submit" value="{$submitbutton}" />
		</form>
		</p>
		<!-- headlines  -->
		<xsl:for-each select="/rss/headlinelist/headline">
			<a><xsl:attribute name="href">
			<xsl:value-of select="hlink"/>
			</xsl:attribute><xsl:value-of select="htitle"/></a>
			<br/>
		</xsl:for-each>
	</body>
</html>
</xsl:template>
</xsl:stylesheet>

この方法では、ローカライズされたストリングは gettext のようなツールで抽出されるのではなく、各ロケールが独自の XSL テンプレートを持っています。言語学的なコンテキストはもはや抽象化されていないので、アプリケーションを管理するための作業負荷の分散が容易になるはずです。そのため、Web 開発者やローカライズ・チーム、あるいは製品のマネージャーであっても、重大ではないバグの修正や、UI に限定した機能要求などに対して、責任を持って行うことができます。

ビュー・クラスは、PHP V5 に付属する XSL サポートと、データ・モデルと XSL テンプレートを使って HTML を作成します。PHP V4 では、方法が少し異なります。PHP V4 での方法も、古いアプリケーションをローカライズする必要のある場合のコメントとして示してあります。ほとんどの場合、XSLT はデフォルトで有効になっていますが、このすべてを動作させるためには PHP インストールの中で XSLT 処理を有効にする必要があるかもしれません。リスト 9 は XSL 変換を示しています。

リスト 9. XSL 変換 (View.php)
	public function asHTML() {
		$xml = new DomDocument;
		$modelxml = $this->model->asXML();
		#system('echo " ' . $modelxml . ' " > /tmp/l.txt');
		$xml->loadXML($modelxml);
		$xsl = new DomDocument;
		$xsl->load($this->template);
		$proc = new xsltprocessor;
		$proc->importStyleSheet($xsl);
		$html = $proc->transformToXML($xml);
		
#      Following is XSL transformation syntax for PHP4
#		$xh = xslt_create();
#		$arguments = array ('/_xml' => \
$this->model->asXML(),  '/_xsl' => $this->template);
#		$html = xslt_process($xh, 'arg:/_xml', $this->template, 
#                                          NULL, $arguments, $this->parameters);
#		xslt_free($xh);

		return $html;
	}

多くのチームが関係する場合には、ストリングを抽出し、マスター・テンプレートから XSL テンプレートを生成した方が、やはり得策かもしれません。これは通常、GMS (globalization management system) によって行われます。その場合 Web 開発者は、その企業が優先する言語を使ってデフォルトの XSL テンプレートのみに対して作業を行い、翻訳者は GMS の機能を使って (場合によっては SYSTRAN のようなコンピューター補助による翻訳システムを使って) 翻訳作業を行います。

開発が終了し、実動用にリリースする準備が整うと、通常のローカライズ・プロセスは次のようになります。

  • GMS はコア XSL テンプレートからすべてのテキストを抽出し、翻訳データベースを更新します。
  • ローカライズ・チームは翻訳データベースを使って新しいストリングを翻訳し、また変更されたストリングを翻訳し直します。
  • GMS は、翻訳データベースのローカライズされた XSL テンプレートを、ロケールごとに再構成します。

GMS を使うことによる利点はありますが、チームが小さな場合や、成熟したアプリケーションで変更がほとんどない場合には、あまり意味がないかもしれません。これまでに触れたすべてのツールと同様、皆さんは自分が使おうとするものを取得し、実装し、サポートすることによる利点とコストの両方を理解する必要があります。


まとめ

こうした短い記事では、皆さんが突き当たる可能性のあるすべての課題を網羅することはできません。例えば、ここでは文字エンコーディングや日付、通貨単位、数字一般、住所、電話などの扱いに関しては説明しませんでした。ほとんどの場合、日付や通貨を、そのロケールに適切な形式でフォーマットし、表示する必要があります。また、国際ユーザーがフォームに通貨の額や日付を入力する場合には、それらを検証し、解釈するための方法を開発者が理解している必要があります。

とはいえ、この記事で説明した方法で、アプリケーションのローカライズに必要なことの 80% は処理できるはずです。既に存在しているアプリケーションを扱う場合には、そして時間と予算の制約がある場合には、あまり大がかりではない改造方法に注目する方が得策です。新しいアプリケーションを開発する場合、あるいは既存アプリケーションをローカライズするために十分なリソースがある場合には、当然ながら、可能な限り積極的な方法を採用することを恐れるべきではありません。そうすることで、製品を適切にローカライズできるだけではなく、どのようなバグ修正が発生し、どのような機能が追加されたとしても、今後のアプリケーションの管理作業をずっと楽にすることができます。

注意

  1. .tar ファイルには、2 つの必須 PEAR モジュール (XML_RSS と Config) を除き、完全なソースコードが含まれています。また、PHP インストールで XSLT が有効になっていることを確認する必要があります。

ダウンロード

内容ファイル名サイズ
Sample scriptsos-php-intl.zip12KB

参考文献

学ぶために

  • Wikipedia にはソフトウェアのローカライズGMS に関する充実した入門解説があります。
  • GNU は gettext. のインストール方法と使い方を学ぶための出発点として好適です。
  • Michael Kay による developerWorks の記事、「XSLTはどのような言語か」は、XSLT について学ぶための出発点として好適です。
  • SYSTRAN は、市場にあるコンピューター補助による翻訳システムの中で最も有名なものの 1 つです。
  • 「5 つの共通 PHP デザイン・パターン」を読み、PHP でデザイン・パターンを使う方法を学んでください。
  • 「Zend Framework を理解する」も MVC と PHP に関する記事として好適です。
  • IBM developerWorks の PHP project resources を訪れ、PHP について学んでください。
  • developerWorks technical events and webcasts で最新情報を入手してください。
  • IBM オープンソース開発者にとって関心のある、世界中で今後開催される会議や業界展示会、ウェブキャスト、その他のイベントについて調べてみてください。
  • developerWorks の Open source ゾーンをご覧ください。オープンソース技術を使った開発や、IBM 製品でオープンソース技術を使用するためのハウ・ツー情報やツール、プロジェクトの更新情報など、豊富な情報が用意されています。
  • developerWorks podcasts では、ソフトウェア開発者のための興味深いインタビューや議論を聞くことができます。

製品や技術を入手するために

  • 皆さんの次期オープンソース開発プロジェクトを IBM trial software を使って革新してください。ダウンロード、あるいは DVD で入手することができます。

議論するために

  • developerWorks の PHP Developer Forum は、PHP 開発者の議論の場として、さまざまな話題を提供しています。PHP のスクリプトや関数、構文、変数、PHP のデバッグなどに関する質問、その他 PHP 開発者に関係するあらゆる話題に関して投稿することができます。
  • developerWorks blogs から developerWorks のコミュニティーに加わってください。

コメント

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=Open source
ArticleID=249835
ArticleTitle=PHP アプリケーションを国際化する
publish-date=01162007