timurv Smarty Rookie
Joined: 07 Sep 2004 Posts: 8 Location: Russia, Kazan
|
Posted: Sat Oct 23, 2004 12:07 pm Post subject: i18n module based on AzteK |
|
|
Code: |
<?
// $Id: i18n.inc 6 2004-10-13 17:24:40Z timurv $
require_once dirname(__FILE__).'/'.'base_class.inc';
class I18n extends BaseClass {
var $dir;
var $base_lang;
var $lang;
var $module;
var $module_file;
var $common_file;
var $common_xml_data;
var $module_xml_data;
var $lang2locale = array(
'ru' => 'ru_RU.cp1251',
'en' => 'en_US',
);
var $_args;
var $_def_args = array(
'dir' => 'locale',
'lang' => null,
'base_lang' => 'ru',
'module' => null,
'common_file' => 'common.xml',
);
function I18n($args)
{
BaseClass::Constructor($args);
}
function t($string, $args = array())
{
$translate = '';
if ($this->lang && $this->lang != $this->base_lang)
{
$this->_loadXmldata();
// try to search in module file
if (is_array($this->module_xml_data))
$translate = $this->_getValueFromXml($string, $this->module_xml_data);
// if module undefined or translate not found, try common file
if (!$translate && is_array($this->common_xml_data))
$translate = $this->_getValueFromXml($string, $this->common_xml_data);
if (!$translate)
$translate = $string . ' ^';
}
// return transleted result or given string
return strtr($translate ? $translate : $string, $args);
}
function setLang($lang)
{
$this->lang = $lang;
$this->setLocaleFromLang();
}
function setLocaleFromLang($types = null)
{
if (is_null($types))
$types = array(LC_TIME, LC_CTYPE);
$locale = $this->lang2locale[
$this->lang && array_key_exists($this->lang, $this->lang2locale)
? $this->lang : $this->base_lang
];
foreach ($types as $type)
setlocale($type, $locale);
}
function _loadXmldata()
{
// load common data
if (empty($this->common_xml_data))
$this->common_xml_data = $this->_getXmlTree(
$this->_getXmlFilePath($this->common_file)
);
// load module data if need it
if ($this->module)
{
if (!$this->module_file)
$this->module_file = $this->module . '.xml';
if (empty($this->module_xml_data))
$this->module_xml_data = $this->_getXmlTree(
$this->_getXmlFilePath($this->module_file),
false
);
}
}
function _getXmlFilePath($file)
{
return $this->dir . '/' . $this->lang . '/' . $file;
}
function _getValueFromXml($key, &$xml)
{
foreach ($xml[0]['children'] as $tag)
if ($tag['tag'] == 'MESSAGE')
if ($tag['children'][0]['value'] == $key)
if ($tag['children'][1]['value'] != '')
return $tag['children'][1]['value'];
}
function _getChildren($vals, &$i)
{
$children = array();
if (!isset($vals[$i]['attributes']))
{
$vals[$i]['attributes'] = '';
}
while (++$i < count($vals))
{
if (!isset($vals[$i]['attributes']))
{
$vals[$i]['attributes'] = '';
}
if (!isset($vals[$i]['value']))
{
$vals[$i]['value'] = '';
}
switch ($vals[$i]['type'])
{
case 'complete':
array_push($children, array(
'tag' => $vals[$i]['tag'],
'attributes' => $vals[$i]['attributes'],
'value' => $vals[$i]['value']
));
break;
case 'open':
array_push($children, array(
'tag' => $vals[$i]['tag'],
'attributes' => $vals[$i]['attributes'],
'children' => $this->_getChildren($vals, $i)
));
break;
case 'close':
return $children;
break;
}
}
return $children;
}
function _getXmlTree($file, $die = true)
{
if (file_exists($file))
{
$data = implode('', file($file));
$xml = xml_parser_create();
xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
xml_parse_into_struct($xml, $data, $vals, $index);
xml_parser_free($xml);
$tree = array();
$i = 0;
array_push($tree, array(
'tag' => $vals[$i]['tag'],
'attributes' => $vals[$i]['attributes'],
'children' => $this->_getChildren($vals, $i)
));
return $tree;
}
else
{
if ($die)
trigger_error('File ' . $file . ' does not exists!', E_USER_ERROR);
return null;
}
}
}
/*
NAME
Internalization Class
SYNOPSIS
$i18n =& new I18n(array(
'dir' => '/usr/locale',
));
$i18n->lang = 'eng'; // setup lang
$i18n->module = 'test'; // setup module.
echo $i18n->t('test');
echo $i18n->t('%u: hi', array('%u' => 'Neo'));
DESCRIPTION
If string for traslation not present in module lang file ($i18n->module . '.xml')
then it may be found at common.xml
Simple module xml:
<?xml version="1.0" encoding="windows-1251" ?>
<locale lang="eng">
<header>
<project>Default project</project>
<module>common</module>
<lang>English</lang>
</header>
<message>
<id>тест</id>
<string>test</string>
</message>
</locale>
*/
?>
|
Additional class
Code: |
<?
// $Id: base_class.inc 6 2004-10-13 17:24:40Z timurv $
class BaseClass {
function Constructor($args = array())
{
$this->$_args = count($args) ? $args : $this->_def_args;
$this->_loadArgs();
}
function _chArgs($arg_key)
{
$args = $this->$_args;
return $args[$arg_key] ? $args[$arg_key] : $this->_def_args[$arg_key];
}
function &array_slice_by_keys(&$array, &$keys)
{
$ret = array();
for (
$i = sizeof($keys);
$i-- ;
$ret[] = $array[$keys[$i]]
);
return $ret;
}
function _loadArgs()
{
if (count($this->_def_args))
foreach (array_keys($this->_def_args) as $key)
{
$this->$key = $this->_chArgs($key);
}
}
}
/*
NAME
Simple Base Class
SYNOPSIS
class NewClass extends BaseClass {
function NewClass( $args = array() ) {
BaseClass::Constructor($args); // setup all nedded values and default values
}
}
U're must overload _loadArgs in new clases, that usen BaseCalss as extends
for valid work
*/
?>
|
And smaty plugin:
Code: |
<?
// $Id: block.t.php 11 2004-10-13 18:07:52Z timurv $
function smarty_block_t($params, $string, &$smarty)
{
if ($string)
{
$app =& $smarty->get_template_vars('app');
foreach ($params as $key => $value)
{
$params["%$key"] = $value;
unset($params[$key]);
}
echo is_object($app->i18n) ? $app->i18n->t($string, $params) : $string;
}
}
?>
|
There is $app->i18n - refer to i18n class object[/code] |
|