|
Smarty
WARNING: All discussion is moving to https://reddit.com/r/smarty, please go there! This forum will be closing soon. |
|
View previous topic :: View next topic |
Author |
Message |
fabhren Smarty Rookie
Joined: 29 Jun 2003 Posts: 9
|
Posted: Fri Aug 01, 2003 9:03 am Post subject: My multilang solution |
|
|
Greetz y'all,
I decided to 'share my lovin`' and show what a mess i made with AZTEK b-e-a-u-t-i-f-u-l-l multilang solution.
Put up a dir called xmlang. All files are [template_name]_[lang_initials].xml (eg index_de.xml).
And it goes:
Code: |
<?xml version="1.0" encoding="utf-8" ?>
<xmlang lang="de">
<header>
<project>Project Name</project>
<create>2003-01-12 17:24-0500</create>
<revise>2003-01-15 19:15-0500</revise>
<trans>Your Name - Your Email</trans>
<lang>Deutsch</lang>
</header>
<message>
<id>10190</id>
<string>Vorwort</string>
</message>
</xmlang>
|
As you can see, I indexed all translations. It gets complicated to do a decent translation when working with larger translation blocks. This way I can make an app that gets all english xml and give the option for one to build a new language.
Here goes the tpl:
Code: |
<!-- 1o index.php -> header.tpl -->
<HTML>
<HEAD>
{popup_init src="$sJsDir/overlib.js"}
<TITLE>{#sTitle#}</TITLE>
<META content="{#sAuthor#} © {#sYear#}" name='Author'>
<META content="v1.0 ¤ 29-6-2003 " name='Template Version'>
{include file="css_style.tpl"}
</HEAD>
<BODY leftMargin="0" topMargin="0" MARGINHEIGHT="0" MARGINWIDTH="0" bgcolor="#ffffff">
<HR ALIGN="LEFT" WIDTH="100%"></DIV><DIV CLASS="PREFACE"><A NAME="PREFACE">{translate mlIndex=10190 mlPage=$mlPage mlLang=$mlLang}Preface{/translate}</A><P>
</BODY>
</HTML>
|
As you can see, and I believe herein lies the major difference, I keep the translation because designers can see it. I pass on the index, the multipage (index) and the language I want it translated to (de).
Here is the block.translate.php:
Code: |
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* File: block.translate.php
* Type: block
* Name: translate
* Purpose: translate a block of text
* Author: John (AZTEK) Downey
http://delusive.dyn.ee
http://sage.dev.box.sk
http://blacksun.box.sk
* Revised: Fabhren (erocha@fiveq.pt)
* -------------------------------------------------------------
*/
$xml = array();
function smarty_block_translate($params, $content, &$smarty) {
foreach($params as $key => $value) {
$params["%$key"] = $value;
unset($params[$key]);
}
if (!is_null($content)) print(t($content,$params));
}
function t($string, $args = array()) {
global $xml;
if(empty($xml)) {
$xmlfile = SITE_LANG.$args["%mlPage"]."_".$args["%mlLang"].".xml";
if(file_exists($xmlfile)) {
$xml = getXmlTree($xmlfile);
} else {
return strtr($string, $args);
}
}
foreach($xml[0]['children'] as $tag) {
if($tag['tag'] == "MESSAGE") {
if($tag['children'][0]['value'] == $args['%mlIndex']) {
if($tag['children'][1]['value'] != "") {
return strtr($tag['children'][1]['value'], $args);
}
}
}
}
return strtr($string, $args);
}
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' => getChildren($vals, $i)));
break;
case 'close':
return $children;
break;
}
}
return $children;
}
function getXmlTree($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' => getChildren($vals, $i)));
return $tree;
}
?>
|
Here ! Hope someone finds it useful.
Bye
[/code] |
|
Back to top |
|
messju Administrator
Joined: 16 Apr 2003 Posts: 3336 Location: Oldenburg, Germany
|
Posted: Fri Aug 01, 2003 9:37 am Post subject: |
|
|
I also like Azteks approach, although i never used it. There is just one thing that joscha mentionend ages ago ( http://www.phpinsider.com/smarty-forum/viewtopic.php?t=84&p=327#327 ) that should not be underestimated: the use of a prefilter for translation.
if the translation is done in a prefilter (with distinct compile_ids for each language) the translation can be done at compile-time of the template and not at display-time (like with a block-function). this is neglibible if you employ caching on your site, but if not, a prefilter would boost performance tremendously: the xml-files don't even have to be loaded and parsed anymore when displaying the page, once it was compiled.
just my 2c. |
|
Back to top |
|
fabhren Smarty Rookie
Joined: 29 Jun 2003 Posts: 9
|
Posted: Fri Aug 01, 2003 11:33 am Post subject: |
|
|
I've checkec joscha solution but when you're dealing with heavy hitting db's like oracle, and you'll have to dump a bundle o'dough in extra language packs , i'd rather build a small library of languages in xml, even if it takes the extra time to compile .
As I am thinking of cacheing most of the scripts, those that are heavy on text are always cached, while the dynamic one's have less text to translate .
In any case, xml to db is always a possibility ( when we can pay up for the extra functionality ) |
|
Back to top |
|
messju Administrator
Joined: 16 Apr 2003 Posts: 3336 Location: Oldenburg, Germany
|
Posted: Fri Aug 01, 2003 12:25 pm Post subject: |
|
|
maybe i misunderstand you or you misunderstood me.
i suggested a prefilter that does merely the same as your (or azteks (?)) block.translate.php . it should use the same xml-files and, if doable, use the same syntax in the templates as block.translate.php does. |
|
Back to top |
|
fabhren Smarty Rookie
Joined: 29 Jun 2003 Posts: 9
|
Posted: Fri Aug 01, 2003 1:22 pm Post subject: my bad |
|
|
You're right messju I completely misunderstood you. That was, in fact, what I had in mind. I would keep the same structure but filter it a lot faster and having the complementary advantage to compile with a different compile_id for each language.
But I am just a small shrimp in this ocean of smartiness . I am just beggining to grasp the extensiability of it all.
If anyone already has this whole prefilter business sorted out , it would make my life a whole lot easier
Thanx
Fabhren |
|
Back to top |
|
messju Administrator
Joined: 16 Apr 2003 Posts: 3336 Location: Oldenburg, Germany
|
Posted: Fri Aug 01, 2003 2:30 pm Post subject: |
|
|
okay, some lunchbreak-hacking:
(i took azteks stuff from http://www.phpinsider.com/smarty-forum/viewtopic.php?p=326#326
to have functiont t() etc. )
[php:1:08301de9da]
<?php
function smarty_pcallback_translate($match) {
global $__compiler;
$_ld = $__compiler->left_delimiter;
$_rd = $__compiler->right_delimiter;
$string = $match[2];
$attrs = $__compiler->_parse_attrs($match[1]);
$params = array();
foreach ($attrs as $key=>$value) {
$params["%$key"] = $_ld . 'php' . $_rd
. ' echo ' . $value . '; '
. $_ld . '/php' . $_rd ;
}
return t($string, $params);
}
function smarty_prefilter_translate($source, $compiler) {
require_once($compiler->_get_plugin_filepath('shared', 'translate'));
$GLOBALS['__compiler'] =& $compiler;
$_pld = preg_quote($compiler->left_delimiter, '!');
$_prd = preg_quote($compiler->right_delimiter, '!');
$source = preg_replace_callback("!${_pld}translate(.*)$_prd(.*)$_pld/translate$_prd!Us",
'smarty_pcallback_translate', $source);
unset($GLOBALS['__compiler']);
return $source;
}
?>
[/php:1:08301de9da]
i know i won't win a price for beauty with it and there are some questionable design-issues with the one above, but aztek's example is working with it and maybe it's a starter for somebody who is in need of this
greetings
messju |
|
Back to top |
|
fabhren Smarty Rookie
Joined: 29 Jun 2003 Posts: 9
|
Posted: Sat Aug 02, 2003 3:19 pm Post subject: prefilter cant read template vars |
|
|
Hyia messju,
Been fiddling witcha code and no can work , although it was an awesome solution , but only in a postfilter stage.
If you check in the beginning I was sending the language by php to the template. If this is a prefilter, it parses BEFORE the var gets any value and afterwards he'll try to get the xml and it'll crash and burn .
Do you have a hint to make it a postfilter ?
Thanx a lot in advance
Fabhren |
|
Back to top |
|
messju Administrator
Joined: 16 Apr 2003 Posts: 3336 Location: Oldenburg, Germany
|
Posted: Sat Aug 02, 2003 6:41 pm Post subject: |
|
|
hmm, making it a postfilter won't gain you anything.
as a hint: look at the results of $compilter->_parse_attrs();
you'll get a hash array with the attribute-name as a array-key and the php-code to obtain the attribute-value as the array-value.
if (you don't need compatibility to php5 yet and) do "$this =& $__compiler;" you can eval the array-values and should get the correct results (i hope i didn't spoil and hinted too much now). but this only works if the values where assigned from php and not within a template.
another way would be using $__compiler->compile_id to get the $lang and $__compiler->_current_file to get the template-name.
HTH and have a nice weekend
messju |
|
Back to top |
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|
|