CakePHP(1.1)で多言語対応してみる。
adminルーティングで振り分けも考えたけれど、ちょっと用途が違うみたい。
ページは、ルーティングで切り替える。
/servie/index
で日本語
/en/servie/index
で英語
を表示したい場合。
app/config/routes.php
に、
$Route->connect('/en/:controller/:action/*', array('controller' => ':controller', 'action' => ':action', '*'));
を追加。
これで
en/service/index
にアクセスすると、
serviceアクションのindexが呼ばれる。
次に、読み込む言語ファイルを設定したいので、
app/config/bootstrap.php
に、
$bits = explode('/', $_GET['url'], 2);
$GLOBALS['lang'] = ($bits[0] == 'en')? 'en' : 'ja';
とグローバル変数に言語変数を入れる。
その言語変数により、各設定ファイルを読み込む。
コントローラーのリダイレクト($this->redirect)を修正
app/app_controller.php
で、redirect関数をオーバーライドする。
function redirect($url, $status = null)
{
if ($GLOBALS['lang'] != 'ja')
{
$url = "/" . $GLOBALS['lang'] . $url;
}
parent::redirect($url, $status);
}
また、テンプレートの各リンクは、htmlヘルパーで、
$html->url()で記述。
app/view/helper/html.phpの、
url()関数の、
if (isset($this->plugin)) {
$base = strip_plugin($this->base, $this->plugin);
} else {
$base = $this->base;
}
の下に、
if ($GLOBALS['lang'] != 'ja')
{
$base .= '/'.$GLOBALS['lang'];
}
を追加。
また、各言語毎にレイアウト/テンプレートファイルがある場合、render関数をオーバーライドする必要がある。
画面のレンダリング時に、適切な言語のテンプレートを読んでくれないので、
app/app_controller
にrender()関数を追加。
function render($action = null, $layout = null, $file = null)
{
if (!$action)
{
$action = $this->action;
}
if (!$layout)
{
$layout = $this->layout;
}
if ($GLOBALS['lang'] != 'ja')
{
$action = sprintf('%s/%s', $GLOBALS['lang'], $action);
$layout = sprintf('%s/%s', $GLOBALS['lang'], $layout);
}
parent::render($action, $layout, $file);
}
これでひとまずは、日本語版と英語版が同じコントローラーで切り替え出来た。
※補足
CakePHPで現在の実行中のアクションの取得は、$this->action
beforeRender()関数で、var_dump($this)を実行すると、色々と出て来た。