読者です 読者をやめる 読者になる 読者になる

AS3 アプリケーションの国際化

という内容で、Coolin Moock さんを囲むの会で as3gettext の発表してきました。アウェイな発表が出来て良かったです(ぇー)。コリンさんは日本語もうまく(ギザとかテラとか使えるレベル)、ジョークを交えながらトークしてくれて面白かったです。まだ普段あまり会えなかった ASer の方々と懇談会などでお話しできて楽しかったです。ありがとうございました。

AS3 アプリケーションの国際化

と時間があったらその他…

自己紹介

ActionScript と自分

ActionScript と仕事

はてなワールド

  • 実際の地図上を歩いてチャットしたり
  • 2D のぺらぺらを 3D にマッピング
  • メッセージングサーバは POE + 独自テキストプロトコル
    • Perl Object Environment

はてなワールド

実はきちんと国際化されてる

AS3 で国際化手法

  • flex フレームワーク
    • mx.resources.ResourceBundle
    • …が、面倒
    • 使い方も結構複雑
  • もっと簡単に、flex でなくとも使いたい

gettext

var message:String = 'hello colin!';
// gettext
var message:String = _('hello colin!');

gettext

  • プログラマ・翻訳者の分業
  • 様々な gettext ユーティリティが利用可能
    • poEdit
    • 自動で一部翻訳
    • Web 上から編集
  • Web アプリケーションフレームワークとファイルの共用
  • これが AS3 で使えたら…

gettext for ActionScript3

  • というわけで最低限の機能を実装してみました

gettext を使う流れ

  1. ソースの国際化したい文字列を _() で囲む
  2. as3gettext コマンドでテンプレートを作成
  3. 国際化したい言語の po ファイルを作成
  4. as3gettext コマンドで XML ファイルを作成
  5. GetText.initLangFile(xml) をアプリケーションの初期化時に行う
  6. 完了

DEMO

  1. ソースの国際化したい文字列を _() で囲む
  2. as3gettext コマンドでテンプレートを作成
  3. 国際化したい言語の po ファイルを作成
  4. as3gettext コマンドで XML ファイルを作成
  5. GetText.initLangFile(xml) をアプリケーションの初期化時に行う
  6. 完了

実装周りのお話

_('string');

『 _ 』 でメソッド呼び出すのはどうやる?

  • ライブラリパスに 『_.as』 というファイルを用意
    • すると import せずにとも、どこからでも利用可能
// _.as
package {
import com.rails2u.gettext.GetText;

public function _(str:String, ... args):* {
return GetText._(str, args);
}
}

おまけ・$.as でグローバル変数

パスの最上位に 『$.as』 を用意

package {
import flash.utils.Dictionary;
public var $:Dictionary = new Dictionary;
}

するとどこからでもグローバル変数ぽく利用可能

$.POST_URL = 'http://example.com/post_url';
// 別のファイルから
var url:String = $.POST_URL;

as3gettext の実装

  • gettext のコアの実装は ruby-gettext を利用
    • AS3 の簡易パーサ
    • XML の作成

を行っているだけ

mxml (flex)での利用

mxml でもまんま利用可能

  • Application の preinitialize 時
    • GetText.initLangFile(xml)
    • GetText.locale = 'lang'
  • mxml での文字列で "{_('message')}" する
<mx:Label id="hello" text="hello"/>
// が
<mx:Label id="hello" text="{_('hello')}"/>
  • mxml では {} の内側を展開してくれるため可能

as3gettext のインストール

gem install as3gettext 

その後、ライブラリパスを通す

ソースコード

AS から JS の呼び出し

  • HTML と連携するときに重宝
  • ExternalInterface.call で呼び出せる
    • ちょっと面倒
    • 再帰呼び出しができない
    • 値の代入も工夫しないとできない

そこで JSProxy

JSProxy.proxy.$alert('foo'); 
var body:String = 
  JSProxy.proxy.document.
  body.$innerHTML; 
JSProxy.proxy.document.body.
  style.$backgroundColor = 
  '#FF0000';

途中の状態の保持

var location:JSProxy = JSProxy.proxy.location;
var browserUrl:String = location.$href;
var hostname:String = location.$hostname;
location.$href = 'http://www.hatena.ne.jp/';

その他フォームの値をセットし送信したりいろいろ…

JSProxy 実装の話

  • Proxy クラスを継承
    • メソッドやプロパティ呼び出しにフック可能
    • スタックにどういうメソッドが、どういう引数で呼び出されたかを貯める
    • $ 付きでメソッドが呼ばれたら実際に JS を発行する

JSProxy 実装の話

  • JSProxy.proxyLogger にログ取り関数をセット
    • 実際に呼ばれる JS が解る
JSProxy.proxyLogger = trace;
JSProxy.proxy.document.
  getElementsByTagName('input')[0].$value = 'test';
(function(_0, _1) {setTimeout(function(){ 
  try{
    document.getElementsByTagName(_0)[0].value = _1
  } catch(e) {};
}, 0);})