Template Strings.
This link might help a little bit:
Does PHP have a feature like Python's template strings?
What my main issue is, is to know if there's a better way to store Text Strings.
Now, is this normally done with one folder (DIR), and plenty of single standalone files with different strings, and depending on what one might need, grab the contents of one file, process and replace the {tags} with values.
Or, is it better to define all of them inside one single file array[]?
greetings.tpl.txt
['welcome'] = 'Welcome {firstname} {lastname}'.
['good_morning'] = 'Good morning {firstname}'.
['good_afternoon'] = 'Good afternoon {firstname}'.
Here's another example, https://github.com/oren/string-template-example/blob/master/template.txt
Thx in advance!
Answers that include solutions, that state that one should use include("../file.php"); are NEVER ACCEPTED HERE. A solution that shows how to read a LIST of defined strings into an array. The definition is already array based.
To add values to templates, you can use strtr. Example below:
$msg = strtr('Welcome {firstname} {lastname}', array(
'{firstname}' => $user->getFistName(),
'{lastname}' => $user->getLastName()
));
Regarding storing strings, you can save one array per language and then load only relevent one. E.g. you'll have a directory with 2 files:
language
en.php
de.php
Each file should contain the following:
<?php
return (object) array(
'WELCOME' => 'Welcome {firstname} {lastname}'
);
When you need translations, you can just do the following:
$dictionary = include('language/en.php');
And the dictionary will then have an object that you can address. Changing the example above, it will be something like this:
$dic = include('language/en.php');
$msg = strtr($dic->WELCOME, array(
'{firstname}' => $user->getFistName(),
'{lastname}' => $user->getLastName()
));
To avoid the situation when you don't have the template in dictionary, you can use a ternary operator with the default text:
$dic = include('language/en.php');
$tpl = $dic->WELCOME ?: 'Welcome {firstname} {lastname}';
$msg = strtr($tpl, array(
'{firstname}' => $user->getFistName(),
'{lastname}' => $user->getLastName()
));
What people usually do to be able to edit the texts in db, you can have a simple export (e.g. var_export) script to sync from db to files.
Hope this helps.
OK John I will elaborate.
The best way is to create a php file, for each language, containing the definition of an array of texts, using printf format for string substitution.
If the amount of text is very large, you might consider partitioning it further. (a few MB is usually fine)
This is efficient in production, assuming the OS has a well tuned file cash. Slightly more so, it you use numerical indexes to the array.
It is much more efficient to let php populate the array, then to do it your self, reading a text file. this is after all, I assume, static text?
If production performance is not an issue, please disregard this post.
greetings_tpl_en.php
$text_tpl={
'welcome' => 'Welcome %s %s'
,'good_morning' => 'Good morning %s'
,'good_afternoon' => 'Good afternoon %s'
};
your.php
$language="en";
require('greetings_tpl_'. $language .'php');
....
printf($text_tpl['welcome'],$first_name,$last_name);
printf i a nice legacy from the C language. sprintf returns a string instead of outputting it.
You can find the full description of the php printf format here: http://php.net/manual/en/function.sprintf.php
(Do read Josef Kufner post again, when this is solved. +1 :c)
Hope this helps?
First, take a look at gettext. It is widely used and there is plenty of tools to handle translation process, like xgettext and POEdit. It is more comfortable to use real english strings in source code and then extract them using xgettext tool. Gettext can handle plural forms of practically all languages, which is not possible when using simple arrays of strings.
Very useful function to combine with gettext is sprintf() (or printf(), if you want to output text directly).
Example:
printf(gettext('Welcome %s %s.'), $firstname, $lastname);
printf(ngettext('You have %d new message.', 'You have %d new messages.',
$number_of_new_messages), $number_of_new_messages);
Then, when you want to translate this into language where last name usually precedes first name, you can use this: 'Welcome %2$s, %1$s.'
The second example, the plural form, can be translated using more than two strings, because part of localization file is how plural forms are arranges. While for english it is nplurals=2; plural=(n != 1);, for example in czech it is nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2; (three forms, first is for one item, second for 2 to 4 items and third for the rest). For example Irish language has five plural forms.
To extract strings from source code use xgettext -L php .... I recommend writing short script with the exact command fitting your project, something like:
# assuming this file is in locales directory
# and source code in src directory
find ../src -type f -iname '*.php' > "files.list"
xgettext -L php --from-code 'UTF-8' -f "files.list" -o messages.pot
You may want to add custom function names using -k argument.
You could store all the templates in one associative array and also the variables that are to replace the placeholders, like
$capt=array('welcome' => 'Welcome {firstname} {lastname}',
'good_morning' => 'Good morning {firstname}',
'good_afternoon' => 'Good afternoon {firstname}');
$vars=array('firstname'=>'Harry','lastname'=>'Potter', 'profession'=>'wizzard');
Then, you could transform the sentences through a simple preg_replace_callback call like
function repl($a){ global $vars;
return $vars[$a[1]];
}
function getcapt($type){ global $capt;
$str=$capt[$type];
$str=preg_replace_callback('/\{([^}]+)\}/','repl' ,$str);
echo "$str<br>";
}
getcapt('welcome');
getcapt('good_afternoon');
This example would produce
Welcome Harry Potter
Good afternoon Harry
I installed gettext on a server and want to use for a php script..
I use with 3 languages. The original website is written in english..
Other are french and Italian.
I can without problem change language to French or Italian.. But when I want load the en_EN.mo file to replace the origine text of the php file, the translation are not loaded.
I try many things.. Remove file, replace name.. restart apache..
Nothing.. it work perfectly with all other langage, but impossible to use a english file.
I create new language.. it work too.. but never the en_EN..
All my files langage are in the same tree style
locale
en_EN
LC_MESSAGES
en_EN.mo
fr_FR
LC_MESSAGES
fr_FR.mo
...
if I force to use..
$directory = './locale';
$domain ='en_EN';
$locale ='en_EN';
putenv('LC_ALL='.$locale);
setlocale(LC_ALL, $locale);
bindtextdomain($domain, $directory);
textdomain($domain);
bind_textdomain_codeset($domain, 'UTF-8');
no result..
My problem is that I have no idea how to debug it ? Where can I find a log or something to help ? Where see errors ?
It's strange that it work with all lang, but not english.. I use Poedit to create my file, I have create the file many time.. in the same way that other..
Please share your idea :)
I create new language.. it work too.. but never the en_EN..
You misunderstand what the locale string means. It is not “2 language code letters followed by the same letters in uppercase” (that wouldn’t make any sense, would it), it is “language code followed by country code” per ISO 3166. And “EN” is not only not a valid country code for any country that speaks English, it’s not a valid country at all. You’re asking WordPress to run under the English locale (presumably), but only providing it translation files for “English in a made-up country” locale that WP is never going to look for.
You’re thinking of en_US.
I am new to php. On my website I have created a list box of all the languages, but I don't know how to translate my English content to Chinese or to Spanish basically I need a translation code of a particular language.
I have made a langauge table with is attributes as Lang_id, Lang_name.
have a look here: Internationalization in PHP. PHP 5.3 supports native internationalization (http://de.php.net/manual/en/book.intl.php)
Make dedicated page like : "lang.php" having codes like
0 = for English
1 = Italian
2 = French
$me_user_name = array('Username','nome utente','','','Nom d\'utilisateur')
use this array on your site.
for ex.:
echo $me_user_name[0] // to print in english
I am working on a project and there are going to be 3 different languages: English, French and Spanish. This will be defined when the user signs up.
Now in my config file I have the following:
define("DEFAULT_SLOGAN", "The default slogan will go here.");
Until I started realizing that I needed to accept different languages.
The user has an assigned language code (EN, FR, SP). How would I go about having different language strings for each page? Would I need to have something like this:
define("DEFAULT_SLOGAN_EN", "Slogan in english");
define("DEFAULT_SLOGAN_FR", "Slogan in french");
define("DEFAULT_SLOGAN_SP", "Slogan in spanish");
And for each string just have 3 different versions of it? Not too sure the best way to approach this.
Thanks!
A simple strategy that is often used are arrays:
$lang['en'] = array(
'DEFAULT_SLOGAN' => 'The default slogan will go here.',
);
// Same for other languages
Then, in your actual code, make sure that $lang is available (you can use the global keyword for this) and use these arrays.
A better approach would be to create
locale_definitions_EN.php containing
define("DEFAULT_SLOGAN", "The english default slogan will go here.");
local_definitions_FR.php containing
define("DEFAULT_SLOGAN", "The french default slogan will go here.");
etc. and then do something like
include "locale_definitions_$userLocale.php";
This has the advantage, that you don't need the memory to hold the unused other language constants.
I am using Zend_Translate with ini adapter in my project.
I want to know how it is possible to use space character in my ini file.
Sample:
ini file:
Show All = my translation // there is space between Show & All
view scipt:
echo $this->translate('Show All') // it doesnt translate
You can't ( atleast i don't know a way ) , but you got it a bit wrong , think of the first parameter ( "Show All" ) as a constant or a variable , witch has some content that will changed in certan scenarios . For example i would use $this->translate("SHOW_ALL"); .