最近、ちょっと訳あって Codeigniter をいじってます。
すでに PHP が分かっていれば、学習コストも低く、直感的に使えるんでなかなか良いっすよ。
Codeigniter で、国際化するために用意されてる言語クラスですが、通常は以下のようにして使います。
application/language ディレクトリに各言語のサブフォルダ(例:japanese)を用意する。
その中に _lang.php (例:error_lang.php) というファイルを作成して、連想配列 $lang にテキストをセットする。
$lang['language_key'] = "実際に表示されるメッセージ";
Controller で言語ファイルを読み込む。
$this->lang->load('filename');
lang オブジェクトの line メソッドか、lang() 関数で、キーを指定してテキストを取得する。
$message = $this->lang->line('language_key');
// または
echo lang('language_key');
ただ、これだとキーとの対比とか、メンテナンスがめんどくさいので、できれば .mo ファイル作って gettext() で処理したい所です。
幸い Codeigniter は、コアシステムクラスを簡単に拡張できます。
っつうわけで、言語クラス CI_Lang を拡張して gettext で言語リソースを扱えるようにしてみました。
まず、以下の内容で application/core/MY_Lang.php を作成します。
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
* Code Igniter Gettext Extension library
*
* This Library overides the original CI's language class. Needs the $config['language'] variable set as ja_JP or en_EN or fr_FR ...
*
* @package Gettext Extension
* @author wokamoto
* @copyright Copyright (c) 2012
* @license http://www.gnu.org/licenses/lgpl.txt
* @link
* @version Version 0.1
* @since 2012 January, 27th
*/
// ------------------------------------------------------------------------
class MY_Lang extends CI_Lang {
private $gettext_language;
private $gettext_codeset;
private $gettext_domain;
private $gettext_path;
/**
* The constructor initialize the library
*
* @return MY_Lang
*/
function __construct() {
parent::__construct();
}
/**
* This method overides the original load method. Its duty is loading the domain files by config or by default internal settings.
*
* @access public
* @param string $userlang the language, set as ja_JP or it_IT or en_EN or fr_FR ...
* @param string $codeset the codeset, set as UTF-8 or EUC ...
* @return bool
*/
public function load_gettext( $textdomain = false, $userlang = false, $codeset = false, $path = false ) {
$config =& get_config();
$this->gettext_language = $userlang ? $userlang : $config['language'];
$this->gettext_codeset = $codeset ? $codeset : $config['charset'];
$this->gettext_domain = $textdomain ? $textdomain : $this->gettext_domain;
$this->gettext_path = $path ? $path : APPPATH.'language/locale';
/* put env and set locale */
putenv("LANG={$this->gettext_language}");
setlocale(LC_ALL, $this->gettext_language);
/* bind text domain */
bindtextdomain($this->gettext_domain, $this->gettext_path);
bind_textdomain_codeset($this->gettext_domain, $this->gettext_codeset);
textdomain($this->gettext_domain);
return true;
}
/**
* Fetch a single line of text from the language array
*
* @access public
* @param string $line the original string to translate
* @param array $params the plural parameters
* @return string translated
*/
public function line($line = '', $params = FALSE)
{
if ( $params !== FALSE || FALSE === ($value = parent::line($line)) )
$value = $this->_trans( $line, $params );
return $value ? $value : $line;
}
/**
* Plural forms added by Tchinkatchuk
* http://www.codeigniter.com/forums/viewthread/2168/
*/
/**
* The translator method
*
* @access private
* @param string $original the original string to translate
* @param array $aParams the plural parameters
* @return string translated
*/
private function _trans( $original, $aParams = false ) {
if ( !isset($this->gettext_domain) )
return false;
if ( $aParams && isset($aParams['plural']) && isset($aParams['count']) ) {
$sTranslate = ngettext($original, $aParams['plural'], $aParams['count']);
$sTranslate = $this->replaceDynamically($sTranslate, $aParams);
} else {
$sTranslate = gettext( $original );
if ( is_array($aParams) && count($aParams) ) {
$sTranslate = $this->replaceDynamically($sTranslate, $aParams);
}
}
return $sTranslate;
}
/**
* Allow dynamic allocation in traduction
*
* @access private
* @param string $sString
* @return string
*/
private function replaceDynamically($sString) {
$aTrad = array();
for ( $i=1, $iMax = func_num_args(); $i<$iMax; $i++) {
$arg = func_get_arg($i);
if (is_array($arg)) {
foreach ($arg as $key => $sValue) {
$aTrad['%'.$key] = $sValue;
}
} else {
$aTrad['%'.$key] = $arg;
}
}
return strtr($sString, $aTrad);
}
}
そんで、application/language ディレクトリに、以下のようにファイルを言語リソースを配置。
language
+ locale
+ ja_JP (ロケール: ja_JP or en_EN or fr_FR …)
+ LC_MESSAGES
- lang.mo
- lang.po
これを、実際に使う時は以下のようにします。
Controller で言語ファイルを読み込む。
$this->lang->load_gettext('lang', 'ja_JP');
※第一引数は textdomain、第二引数はロケール。
後は、同じように使えます。
$message = $this->lang->line('Hello World!');
// または
echo lang('Hello World!');
WordPress で慣れてるんで gettext 使いたいすよね。





コメント