CakePHP1.2を使った多言語サポート対応時の覚書き

CakePHP 1.2を使った国際化を実装する際に調べて役に立ったサイトを(主に自分のために)纏めておきます。

1)いつも、人知れずお世話になっているサイト「CakePHPのおいしい食べ方」にとても分かりやすい解説がありました。

CakePHP1.2の簡単国際化

CakePHP1.2のbakeで自動生成した画面は、画面に表示される文字列が__('文字列') で囲まれています。これは、簡単に多言語翻訳ができるように配慮されているからです。

引用元: CakePHP のおいしい食べ方: CakePHP1.2の簡単国際化.

2)次に、言語の切り替えをマニュアルでするためのリンクの作り方では、このサイトの情報が役に立ちました。

To better understand the goal and why some things were done the way they were, I’ll summarize the requirements:

1. The app has to support two languages or more (in this case English and Russian)

2. Default language is English

3. The language switching is based on a URL param

4. The URL format should be: example.com/eng/controller/action

5. Language choice should persist in the session and a cookie

引用元: CakePHP URL-based language switching for i18n and l10n (internationalization and localization) « nuts and bolts of cakephp.

なお、自分のサイトでは

  1. 多言語サポートとして英語と日本語をサポート
  2. デフォルトの言語は日本語
  3. 言語はURL paramで変更できる
  4. URLフォーマットは: example.com/ja/controller/action といった感じ
  5. 好みの言語はセッションとクッキーで保持される。

としています。用はWordpressのプラグインで「qTranslate」という便利なプラグインがあるが、同じことをしたい!

なので、こちらの例ではConfigフォルダの中のroutes.phpで以下のように

Router::connect('/:language/:controller/:action/*',
                       array(),
                       array('language' => '[a-z]{3}'));

としていますが、自分は[en]と[ja]など2文字がよかったので以下のようにしました。

Router::connect('/:language/:controller/:action/*', array(), array('language' => '[a-z]{2}'));

で、後は引用元にもあるように、_setLanguage()をapp_controller.phpの中に記述して、beforeFilter()関数から呼び出すようにします。

	function _setLanguage() {

	    if ($this->Cookie->read('lang') && !$this->Session->check('Config.language')) {
	        $this->Session->write('Config.language', $this->Cookie->read('lang'));
	    }
	    else if (isset($this->params['language']) && ($this->params['language']
	             !=  $this->Session->read('Config.language'))) {     

	        $this->Session->write('Config.language', $this->params['language']);
	        $this->Cookie->write('lang', $this->params['language'], null, '20 days');
	    }
	}

さらに、app_helper.phpに以下のurl()関数をオーバーライドする関数を作ってお膳立ては出来上がり。

	function url($url = null, $full = false) {
        if(!isset($url['language']) && isset($this->params['language'])) {
          $url['language'] = $this->params['language'];
        }     

        return parent::url($url, $full);
	}

最後に、肝心のリンクを作ります。
自分はviews/layouts/default.ctpにリンクを作りました。

<p>
    <?php echo $html->link('English', array('language'=>'en')); ?>
</p>
<p>
    <?php echo $html->link('Japanese', array('language'=>'ja')); ?>
</p>

で、出来上がり。
example.com/en/controller/action
で言語を英語に切り替えた後、
example.com/controller/action
でアクセスしても、選択言語が保持されているのを確認します。

自分が作っているCakePHPサイトで挙動が確認できます。
http://labeauty.getmycity.com
(実はまだ多言語サポート対応中のためFooterの一番下にEnglish、Japaneseの隠しリンクがあるw)


xPagesのTabbed PanelをPartial RefreshでAjax化させよう

xPagesのTabbed Panelってとても便利だと思うのですが、デフォルトだと、クリック毎にページ全体を読み直すのでかっこ悪い。
そこで、Partial Refreshを使ってAjax化させてみました。

<xp:panel id="container">
<xp:tabbedPanel id="tabbedPanel1">
<xp:this.selectedTab>
<![CDATA[#{javascript:(null == sessionScope.selectedTabId) ? "tabPanel1" : sessionScope.selectedTabId}]]>
</xp:this.selectedTab>
<xp:tabPanel label="Tab1" id="tabPanel1">
Tab1のコンテンツが入ります。
<xp:eventHandler event="onclick" submit="true" refreshMode="partial" refreshId="container">
<xp:this.action>
<![CDATA[#{javascript:sessionScope.selectedTabId = "tabPanel1"}]]></xp:this.action>
</xp:eventHandler>
</xp:tabPanel>
<xp:tabPanel label="Other" id="tabPanel2">
Tab2のコンテンツが入ります。
<xp:eventHandler event="onclick" submit="true" refreshMode="partial" refreshId="container">
<xp:this.action>
<![CDATA[#{javascript:sessionScope.selectedTabId = "tabPanel2"}]]>
</xp:this.action>
</xp:eventHandler>
</xp:tabPanel>
</xp:tabbedPanel>
</xp:panel>

ここでは、

1)各Tabの中にonclickイベントを作成。
2)Partial UpdateのElementに親タグのID"container"をRefreshIDに指定。
3)onclickイベントの中で、各タブごとに、selectedTabIdを以下のように指定する。
sessionScope.selectedTabId = "tabPanel1"

しかし、これをデザインのプロパティからやろうとすると、操作が難しい(というか出来ない)ので、ソースをガシガシ書いていくのが吉です。

ちなみに、自分の環境では8.5.0までは "_10f.push is not a function"のエラーが出て上手く動いていなかったので、XPages Blogにある通り8.5.1にアップデートしたら問題は解消されました。

Partial refresh and Firefox 3.5, Safari, Opera on 8.5.0 - XPages Blog - The XPages Blog

I just stumbled upon this post in the 8.5 forum: it describes the known problem that partial refreshes on a Domino 8.5.0 server causes the message "_10f.push is not a function".

This happens with Firefox 3.5, Safari 4, Opera and I believe in IE 8, too.There is no workaround at least none I'm aware of but using full refreshes all the time.But: the solution is underway! This is fixed in the upcoming 8.5.1.

引用元: Partial refresh and Firefox 3.5, Safari, Opera on 8.5.0 - XPages Blog - The XPages Blog.


iPhoneでFlashのネイティブ対応が可能に

Appleの「iPhone」上で、Flashアプリケーションの対応を図れるようになると明らかにした。

引用元: アドビ、「Flash Professional CS5」を発表--iPhoneでFlashのネイティブ対応が可能に:アップルセンター - CNET Japan.

これでFlashプログラマーがiPhoneアプリの開発に参入できることになりますね。

Flashから常に敬遠していた自分は負け組みだぁ~(/_;)

今からでも勉強していこうかな・・・ でもうちはデザイン会社じゃないって理由でAdobeの高価なソフトは買ってもらえそうにないので、触るとしたらFlex SDKを使うんだろうけど、これ以上覚える言語を増やしていいのか?と頭の中で警告が鳴る。

それだったらやっぱりiPhoneの開発プラットフォームであるObjective-Cの方が断然興味あり。

あと、やっぱり気になるのがこれ。

Adobeの究極の目標は現在も変わっておらず、Flashを「Safari」ブラウザに統合してiPhoneで提供することが目指されている。同社最高 技術責任者(CTO)のKevin Lynch氏は、インタビューに応えて「ただ1つのウェブのみが存在するということこそ私の願いである」と述べた。

iPhone SafariのFlashプラグインはまだ先になりそうですが、近い将来に是非実現してほしいものです。


Notes 8.5.1クライアントで動くxPagesコンポーネント

Here are two videos that demonstrate how you can used XPages components in the Lotus Notes 8.5.1 client.

引用元: Lotus Domino Designer wiki.

デモの通りだと、とても簡単に実装できそうです♪
Lotus Notes 8.5.1の正式リリースが10月12日らしいので、いまから待ち遠しい。

ちなみに、Lotusphere 2009でBob Balfのセッションで言っていたWebフォームとComposite Applicationのワイヤリングが簡単に出来る機能。セッションでの彼の発言によると8.5.1で実装されるはずなんだけど、あまり聞かないなぁ~。 実装見送りになったのかな?

ワイヤリングする対象をHTMLのDOMをインタラクティブに調べることで簡単に行ってた。 まるでFirebugのElementsを調べる機能みたいでみててかなり感動だったんだけどな・・・


Wordpress の便利なツール ~ 投稿ブックマークレット ~

閲覧中のページへのリンクを貼ったブログの投稿ページを呼び出したり

引用元: Wordpress の便利なツール ~ 投稿ブックマークレット ~.

「Tumblr」の「Share on Tubmlr」ボタンように気に入った記事を引用して簡単に自分の記事を書くことが出来ないかなぁ~とおもってたどり着いた。

ちなみに、引用したい部分を選択してから、「Press This」のボタンを押すだけで簡単に引用して記事がかけます。

Version2.6からすでにデフォルトでバンドルされていたんですね。 自分も知らなかった。

こういった機能といい、TwitterのRetweetといい、「使いやすい」「簡単」ってのがインターネットをドンドン進化させていってますね。

ちなみに、Lotus ConnectionsのDogEarもこうやって簡単にソーシャルブックマークする機能があったな。。。


iWidgetsをLotus Dominoで使える?!

Enabling iWidgets in IBM Lotus Domino Web applications

Lotus Notes and Domino wiki.

明日、早速これをxPagesで動く自前のポータルサイトで試してみます。
いい結果になれば、ここで公表できるかも。