Smarty Forum Index Smarty
The discussions here are for Smarty, a template engine for the PHP programming language.

best way to build a multi-language site with smarty
Goto page Previous  1, 2, 3 ... 11, 12, 13, 14, 15  Next
 
Post new topic   Reply to topic    Smarty Forum Index -> Tips and Tricks
View previous topic :: View next topic  
Author Message
Estupefactika
Smarty Rookie


Joined: 08 Jul 2005
Posts: 9

PostPosted: Wed Apr 18, 2007 9:04 am    Post subject: Reply with quote

Hi, im trying to make smarty templates miltilanguage.

Following http://smarty.incutio.com/?page=SmartyMultilanguageSupport, i did that:

My smarty_ML.php class
Code:

<?php
  require_once ("Smarty.class.php");

  /**
   * smarty_prefilter_i18n()
   * This function takes the language file, and rips it into the template
   * $GLOBALS['_NG_LANGUAGE_'] is not unset anymore
   *
   * @param $tpl_source
   * @return
   **/
  function smarty_prefilter_i18n($tpl_source, &$smarty) {
    if (!is_object($GLOBALS['_NG_LANGUAGE_'])) {
      die("Error loading Multilanguage Support");
    }
    // load translations (if needed)
    $GLOBALS['_NG_LANGUAGE_']->loadCurrentTranslationTable();
    // Now replace the matched language strings with the entry in the file
    return preg_replace_callback('/##(.+?)##/', '_compile_lang', $tpl_source);
  }

  /**
   * _compile_lang
   * Called by smarty_prefilter_i18n function it processes every language
   * identifier, and inserts the language string in its place.
   *
   */
  function _compile_lang($key) {
    return $GLOBALS['_NG_LANGUAGE_']->getTranslation($key[1]);
  }


  class smartyML extends Smarty {
    var $language;

    function smartyML ($locale="") {
      $this->Smarty();

      // Multilanguage Support
      // use $smarty->language->setLocale() to change the language of your template
      //     $smarty->loadTranslationTable() to load custom translation tables
      $this->language = new ngLanguage($locale); // create a new language object
      $GLOBALS['_NG_LANGUAGE_'] =& $this->language;
      $this->register_prefilter("smarty_prefilter_i18n");
    }

....



In my index.php:

Code:
<?php
include_once ("smarty/libs/smarty_ML.php");
  $smarty = new smartyML("en");
  $smarty->loadTranslationTable();
  $smarty->display("myTemplate.tpl");
?>


myTemplate.tpl:
Code:
<html>
  <body>
    ##NG_HELLO_WORLD##<br>
    ##NG_MULTILINE##<br>
    <input type="button" value="##NG_OK##" onclick="alert('##NG_OK##')">
    <input type="button" value="##NG_CANCEL##" onclick="alert('##NG_CANCEL##')">
  </body>
</html>


And my language files:
// English language file
// put in languages/eng/global.lng
NG_OK=Ok
NG_ABORT=Abort
NG_CANCEL=Cancel
NG_MULTILINE=This entry spans 2 lines, this is the first
and this is the second.
NG_HELLO_WORLD=Hello World!<br>How do you do?

// German language file
// put in languages/deu/global.lng
NG_OK=Ok
NG_ABORT=Abbrechen
NG_CANCEL=Abbrechen
NG_MULTILINE=Dieser Eintrag umfasst 2 Zeile, diese ist die erste
und diese ist die zweite.
NG_HELLO_WORLD=Hallo Welt!<br>Wie geht es Dir?

I put them in smarty/languages, its ok?

Well, it doesnt works, template display me NG_HELLO_WORLD for example instead of traslation.
If i put $smarty->loadTranslationTable(); in my index.php an error appears me saying:
Call to undefined function: loadtranslationtable() in /..../smarty/libs/smarty_ML.php on line 44

What are i doing wrong? Thanks for you help
Back to top
View user's profile Send private message
vcrfix
Smarty n00b


Joined: 10 May 2007
Posts: 3

PostPosted: Fri May 11, 2007 10:45 am    Post subject: Building a multilingual site with smarty Reply with quote

I also use the smartyML class for the site. A very good, stable and robust solution, requires no extra coding on my part and only language specific text files.

Very well done !
Back to top
View user's profile Send private message
pvginkel
Smarty n00b


Joined: 04 Aug 2006
Posts: 3

PostPosted: Tue May 22, 2007 2:46 pm    Post subject: A different way using prefilters Reply with quote

I just redid my gettext system. I started out basing it on smarty-gettext, but as mentioned: not every text can be surrounded by a {t} {/t}.

At the basis I still use gettext, but that isn't of consequence to this example. It just means that my message names are natural language. They look like this (note that domains I've allowed for domains):

Code:
[[Text to be translated]]

[[domain!Domain specific text to be translated]]


Next I attach a prefilter with the following code.

Code:
...

$smarty->register_prefilter('translate_template');

...

function translate_template($tpl_source, &$smarty) {
  return preg_replace_callback('/\[\[(?:([\w-_]+)\!)?(.*?)\]\]/',
    'translate_template_item', $tpl_source);
}

function translate_template_item($matches) {
  if ($matches[1] != '') {
    return dgettext($matches[1], $matches[2]);
  } else {
    return gettext($matches[2]);
  }
}


And that's my new system. A few examples on usage.

* Note that I've placed the quotes outside of the brackets. This means they don't have to be translated. This also shows replacing tags:

Code:
{"[[Sign in to %1]]"|escape|replace:'%1':"<b>$title</b>"}


As mentioned earlier: you could place tags like {$title} in your po files and have a construct like this:

Code:
[[Sign in to <b>{$title}</b>]]


They both work equally well, but the first gives you more control and generates less messy translation files.

Note that you have to figure out if you want the escaping to be done in the translate_template_item method or in your smarty code.

* A JS example:

Code:
var delete_prompt = '{"[[This will delete the current file. Are you sure?]]"|wordwrap:50:'\\n'}';


* And the reason I switched to this mechanism (not an actual example of course):

Code:
{assign var=title value="[[A title]]"}


There is one important point I haven't seen mentioned in the posts in this thread concerning translations done using prefilters. Your compiled templates will be language dependent. To fix this, do something like this:

Code:
$smarty->compile_dir = './compiled/' . $_SESSION['lang'];
$smarty->cache_dir = './cache/' . $_SESSION['lang'];

if (!is_dir($smarty->compile_dir)) { mkdir($smarty->compile_dir, 0777, true); }
if (!is_dir($smarty->cache_dir)) { mkdir($smarty->cache_dir, 0777, true); }


This will create a compiled template and cache folder for each language. Not doing this will be very confusing.

Btw: not knowing how gettext works is not an excuse not to use it. It's a great system with a lot of support systems (gtranslator e.g.). I've also had some problems getting it to work. A site like http://www.onlamp.com/pub/a/php/2002/06/13/php.html helps a lot. Also: make sure your system has the locale installed. Don't bother with them manually but check out how your package system supports them. Ubuntu and debian use the following command:

Code:
sudo dpkg-reconfigure locales
Back to top
View user's profile Send private message
mozolici
Smarty Rookie


Joined: 18 Aug 2007
Posts: 21
Location: Suceava / Romania

PostPosted: Sat Aug 18, 2007 7:15 am    Post subject: it`s seems to be a bug Reply with quote

i install the script on my local machine

and it works great
for language "deu" and "eng"

----

but

---
i create a new folder in languages

this folder is "rom" --> from romania

---

i translate the code

NG_ABORT=Abort --eng--> to NG_ABORT=REnunta (renunta is a word in romanian language)

----

script works great in this moment

the problem apper when i want to update this row

NG_ABORT=REnunta
to
NG_ABORT=REnunta bla bla bla bla bla

---- is not working ... don`t want to update

when is see that not working i delete entire folder (romanian folder)

but surprise

in php text appear in my language.. romanian language Neutral
Back to top
View user's profile Send private message Visit poster's website
michuw
Smarty n00b


Joined: 29 Sep 2007
Posts: 1

PostPosted: Sat Sep 29, 2007 1:41 am    Post subject: Re: IntSmarty Reply with quote

Quote:

He talks of the IntSmarty by John Coggswall.... I have been trying to impliment it for a few days now but to no success.. Can anyone offer any help? I am having one weird problem where my L block function will not pick up.. When I put something in between {l} and {/l} all i get is the following errors:
Code:

Warning: Smarty plugin error: [in leftbar.tpl line 4]: unknown tag - 'l' in /var/www/php2/Smarty/Smarty.class.php on line 1889

Warning: Smarty plugin error: [in leftbar.tpl line 4]: unknown tag - '/l' in /var/www/php2/Smarty/Smarty.class.php on line 1889
 
Fatal error: Call to undefined function: () in /var/www/php2/templates_c/N626/N626615291/leftbar.tpl.php on line 8




Weird eh? I have installed the IntSmarty Class. If someone who knows a thing about the block function or IntSmarty, please reply OR e-mail me: na027436@students.cna.nl.ca

THANKS



everyone having such problem with this class just make sure you start with creating new smarty object by calling new IntSmarty not a Smarty class itself. It will work.[/quote]
Back to top
View user's profile Send private message
xces
Smarty Regular


Joined: 09 Apr 2004
Posts: 77

PostPosted: Fri Oct 19, 2007 6:37 am    Post subject: Reply with quote

Guys, i am still struggling with something:
- I once started with PHP, put everything in PHP files.
- Then i went to templates, and finally ended up in Smarty. I still printed the (dutch) errors, messages and validation in both PHP and TPL.
- Untill now, i only print "constants" that is; i have a lot of constants in each file, "define('..key..', '..message..')"

The problem is really that i need to start supporting multiple languages. To quote an old reply i've made in this thread.. (i never got around to implement this).

I think i want to implement this, but i aint sure anymore...
Code:

CREATE TABLE `cms_language` (
  `cms_languageid` bigint(20) NOT NULL auto_increment,
  `language` varchar(20) NOT NULL default '',
  `mnemonic` char(3) NOT NULL default '',
  `countrycode` varchar(5) NOT NULL default '',
  PRIMARY KEY  (`languageid`)
) TYPE=MyISAM;

CREATE TABLE `cms_text` (
  `cms_textid` bigint(20) NOT NULL auto_increment,
  `key` tinytext NOT NULL,
  `variable` tinytext NOT NULL,
  PRIMARY KEY  (`textid`)
) TYPE=MyISAM;


Right now, for instance i have a file which is like this:
./php/manager/invoice/cron/generate.php

Messages in this file have the following "id":
manager_invoice_cron_generate_databaseError
(or)
core_emailInvalid

P.s. i use these "variables" in both PHP files and TPL files, so a prefilter or postfilter is not an option..

This means i have both global messages and messages specific to a file.

The problem is, that i don't know which way to implement this. To be honest i think the 100's of defines take way to much memory, and even more so when i add more langauges. Secondly, if the define is not "set", i just see "core_emailInvalid" in the file instead of "Your email adress is invalid".

So i need to come up with something else, i can:
a) put everything in a database like above, but that
- required (My)SQL on the site
- is harder to maintain
- requires lots and lots of querys
b) put everything in a different file (e.g. 2 PHP files, 2 message files (per lang))
- still hard to maintain
- low memory usage as only that what is required is loaded
- requires some extra coding
c) put everything in 1 big file (per language)
- easy to maintain
- high memory consumption?

I think i'd have to go with option "c", and store it in the session. (e.g. "file changed between page loads, reload and reparse the file). What do you guys think is the best way to go?
Back to top
View user's profile Send private message
m0bius
Smarty n00b


Joined: 14 Oct 2006
Posts: 2

PostPosted: Sat Oct 20, 2007 1:08 am    Post subject: Reply with quote

Hello there,

I'd like to ask if anyone knows what is the overhead of having outputfilters instead of postfilters in order to replace language variables?

I have language variables assigned to template variables that I wanted replaced at the end. However if the cost is too great I am gonna have to think of a different approach to it.

Btw, I am working on the SmartyML class a bit, and I've changed it to support a different language file per template file. If anyone is interested when I have it finished I'll post it here.
Back to top
View user's profile Send private message
dark_0n3
Smarty n00b


Joined: 22 Oct 2007
Posts: 1

PostPosted: Mon Oct 22, 2007 5:42 pm    Post subject: smarty, intsmarty and html_quickform problem Reply with quote

Hello everyone... I readed al 12 pages and I can't find a solution to my problem...only vague answers...

I need to write a form in multiple languages. I use ftml_quickform with smarty... and for translate it IntSmarty which translate the words between{l} and {/l}

Now in my .tpl file I have {$form.ElementName.label} and I want this value to be translated.

How cand I do this because using {l}{$form.ElementName.label}{/l} doesn't work... IntSmarty doesn't see the value from $form.ElementName.label just after the .tpl file was compiled.

I used also the version that use ##NG_NAME## modified with outputfilter but doesn't help me...

Please someone explain me what can I do... thanks
Back to top
View user's profile Send private message
xe912
Smarty n00b


Joined: 25 Oct 2007
Posts: 1

PostPosted: Thu Oct 25, 2007 8:11 am    Post subject: Reply with quote

Hello everyone,

i have found here solution of using smarty with mulitlanguage purpose with xml file. And i would like to ask, is it possible to use this solution, when html is generated in php script and then passed to smarty.

For example, i use form class which generates html code, but i would like to make the labels multilanguage. I tried to add {language}..{/language} in labels, but it is not changed and it is seen in browser.

Thank you for your help!
Back to top
View user's profile Send private message
pbleuse
Smarty n00b


Joined: 26 Mar 2007
Posts: 4

PostPosted: Tue Nov 20, 2007 10:14 am    Post subject: Multi text file with smartyML class Reply with quote

Hi all,

I use smartyML class for multilanguage support, and for me it's the best solution,
because you can give the text file to a non developper and he can translate it easy, no xml code, etc... (but it's why I think, not what I want you think Wink )

Well, I need your help to found a solution for can have multi file .lng
because I need it for separate different section of my site.
example:
global.lng => have all standart expression, menu, button text
presentation.tpl => have the text of site introduction.

I want do that because I want todo a form for create translation (total 14 languages) and one file is bigger.

I see the part of code for use file not name 'global.lng' but what the solution for use both?

Thanks Very Happy
Back to top
View user's profile Send private message
aniltc
Smarty Rookie


Joined: 02 Feb 2007
Posts: 8

PostPosted: Wed Nov 21, 2007 7:43 am    Post subject: Reply with quote

hi
can i use smartyML class for multilanguage website using php ?
any good tutorials how to use it?
thanks
Back to top
View user's profile Send private message Visit poster's website
WanWizard
Smarty n00b


Joined: 22 Nov 2007
Posts: 4

PostPosted: Thu Nov 22, 2007 2:44 pm    Post subject: Reply with quote

I find that a lot of the solutions mentioned in this thread (possibly with the exception of the gettext() method) are quite Smarty centric.

I've been struggling with the issue of localization for a while, basically because I need the locale strings to be available in the application as well. Also, speed is something to take into account.

I've now came up with the following solution:

I store my locale information and my i18n strings in a database table. I have a load_locale() class, that can be called by both PHP and Smarty (using a function). This class uses a caching system comparable to Smarty. If the cache file doesn't exist, or is out of date, a new one is generated when it's called. The cache file only contains array element definitions, ie. $locale['i18nstring'] = "text value";. By including this file the strings are loaded very fast, the only other overhead is a query to determine the max(timestamp) and a file I/O to check the timestamp on the cache file.

This also makes it possible to chop the info into smaller chunks, so you don't have to load info you don't need, and because the array is defined, you can easily include multiple cache files when needed.

To further increase the speed the database check can be switched off. I only use the database in development, my production systems only use the cache files (again, similar to the way Smarty operates).

On top of the database I've made a translation system, so that a team can work on translations independent of the developers. Updates will automatically generate a new cache file, due to an updated timestamp.

This works like a charm for me. Smile

WanWizard
ExiteCMS lead-developer
Back to top
View user's profile Send private message
pbleuse
Smarty n00b


Joined: 26 Mar 2007
Posts: 4

PostPosted: Tue Nov 27, 2007 3:40 pm    Post subject: Multi text file with smartyML class :: solution Reply with quote

Hi, in relation with my request for a solution for can use multiple file.lng with smartyML class, I do this:( I use quote for you can see mod in blue )

Add $_multiFiles var for get filename with declaration
Quote:
// Added $_multiFiles var for multi language files support.
function smartyML ($locale="", $_multiFiles="") {
$this->Smarty();

// Multilanguage Support
// use $smarty->language->setLocale() to change the language of your template
// $smarty->loadTranslationTable() to load custom translation tables
$this->language = new ngLanguage($locale,$_multiFiles); // create a new language object
$GLOBALS['_NG_LANGUAGE_'] =& $this->language;
//$this->register_prefilter("smarty_prefilter_i18n");
$this->register_outputfilter("smarty_prefilter_i18n");
}


Add it in class
Quote:
class ngLanguage {
var $_translatio....
....Tables; // array of all loaded translation tables
var $_multiFiles; //array of multi languages file. ADD FOR MULTI FILES LANGUAGE SUPPORT

function ngLanguage($locale="", $_multiFiles="") {
$this->_languageTable = array(
"ca" => "ca",
.......
"tr" => "tr"
); // to be continued ...
$this->_translationTable = array();
$this->_loadedTranslationTables = array();
foreach ($this->_languageTable as $lang)
$this->_translationTable[$lang] = array();

$this->_defaultLocale = 'en';
if( $_multiFiles != "") $this -> _multiFiles = ( preg_match('/,/', $_multiFiles) ) ? explode(",",$_multiFiles) : array($_multiFiles);
if (empty($locale))
$locale = $this->getHTTPAcceptLanguage();
$this->setCurrentLocale($locale);
}


And construct a new array if there are multi file.lng (_LANG is my constant for language path)
Quote:
if(empty($path))
$path = _LANG . $this->_languageTable[$locale] . '/global.lng';
// die ( $path );
if (isset($this->_loadedTranslationTables[$language])) {
if (in_array($path, $this->_loadedTranslationTables[$language])) {
// Translation table was already loaded
return true;
}
}
if (file_exists($path)) {
$entries = file($path);
// Modification for multi files language
if( count( $this -> _multiFiles ) > 0 ) {
foreach( $this -> _multiFiles as $file ) {
foreach( file(_LANG . $this->_languageTable[$locale] . "/" . $file) as $line ) {
$entries[] = $line;
}
}
}
// End

$this->_translationTable[$language][$path] = array();
$this->_loadedTranslationTables[$language][] = $path;
foreach ($entries as $row) {
if (substr(ltrim($row),0,2) == '//') // ignore comments
continue;


It work fine, but I need your opinion to confirm is a good method and there is not add more charge to server.


Thanks

Very Happy
Back to top
View user's profile Send private message
dritzz
Smarty n00b


Joined: 15 Feb 2008
Posts: 2

PostPosted: Mon Feb 18, 2008 4:37 pm    Post subject: Reply with quote

hi!

Someone can explain to me step by step how to use smartyML class? Cause i've installed this class, i think, in the good way and it doesn't work.

Thanks for help.
Back to top
View user's profile Send private message
piins
Smarty Rookie


Joined: 22 Mar 2008
Posts: 6

PostPosted: Sat Mar 22, 2008 3:02 am    Post subject: smarty i18n gettext compatible plugin Reply with quote

Hi,

we've come up with i18n plugins for Smarty. It allows you to use gettext as you do for php and combine it with smarty-variables as you wish...

you can use _, gettext, ngettext,... in your Smarty template at any point.

Since this is my first post, I can't post the URL directly, but I will do an immediate follow up with the URL.

Hope this helps! Comments are heartily welcome...

Bests,
Charly
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Smarty Forum Index -> Tips and Tricks All times are GMT
Goto page Previous  1, 2, 3 ... 11, 12, 13, 14, 15  Next
Page 12 of 15

 
Jump to:  
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
Protected by Anti-Spam ACP