I have a php/smarty/pear app that has it's own localization implementation that involves using ids for strings and the strings are stored in a db. currently the app is only in English but I will start adding other languages. The current implementation is very poor and basically I'm not a big fan of re-inventing the wheel.
Can anybody recommend what to use for localization? I had used gettext years ago, is that still used or is there something newer and better ?
thanks in advance.
I would use gettext, since it's a mature system and provides features like singular/plural versions of translations.
To be not dependant on the availability of the php extension, you should fall back to http://launchpad.net/php-gettext which provides a pure php implementation of gettext.
gettext has also the big advantage that dozens of tools exist that make it easy to translate those files.
My best advice is to look at how other apps (Drupal, Joomla, Wordpress) handle localization, and implement something similar.
A few of the apps I have delved into have a single ini file for each language that contains STRING-ID="String Value" definitions, where the STRING-ID is similar to a PHP CONSTANT name. These files are then loaded by a localization class, which has functions that handle setting the language to be used (based on a config value or user setting), loading the file, and handle the translation of the STRING-ID into the String Value. You would end up using it like this:
<?php
// config.php
$lang = "DE";
// languages/de.ini
HELLOWORLD="Hallo Welt"
OTHERSTRING="Anderer String"
// example.php
require_once("classes/localization.class.php");
$localize = localization::getInstance();
echo $localize->translate("HELLOWORLD");
?>
This should produce something like Hallo Welt.
Related
I'm writing a webapp in german, so all buttons,text,tooltips etc. are in german for now. But I want to use some kind of template file for the webapp so I can quick change to another language if needed. I thought about textfile that I explode with "\n" and load into a sessionvariable to have always all text the user will need in his session. An other approach would be to parse such a file i.e. a XML document like this:
<?xml version="1.0"?>
<phrase>
<placeholder></placeholder>
<value></value>
</phrase>
where every field has it's own name/value that represents a textsnippet or button or whatever on the website, and then cast it into an object an cache it for everyone. I think the second approach is the best for working with multiple languages for a webapp. Anybody perhaps some pointers what I could do even better, or just post how you did this kind of languagetemplating for mutlinational webpages/webapps in the past.
Since you are looking for a translation solution, I understand you don't use a framework to develop your site, since most of them provide you with solutions to handle translations.
Most frameworks and apps I've seen in php use arrays, where the original sentence is the key and the translation is the value. So, to make easier to translate it to several languages, the key is in english.
In case you use gettext as suggested, or another aproach, it'll be useful also to parse your code to catch all strings to be translated automatically, since it can be a mess doing it manually when the base code grows and you want to keep up to date your translations.
Take a look at GNU Gettext, its very handy for multilanguage support.
The main idea is that you just wrap your words or phrases into a function, like
echo _g('Hello');
so you do not have any engine changes. You will have to add translation files for each language you are using.
You've come up with 2 solutions for storing the data, but I suggest you need to think further about the architecture and take a more complete view of the lifecycle of each request.
Regarding architecture: neither solution scales up to describe an extensive vocabulary very well - although for one or 2 pages it will suffice. The alternative approach, to manage a translation database (such as gettext) which might be overkill - and performs less optimally with small numbers of pages but importantly performance does not deteriorate significantly with large/multiple dictionaries. A compromise solution might be to have a dataset for each URL/language (which might be extracted from a consolidated database).
If it were me, I would not use either method you proposed for storing the data: parsing XML creates a sginficant overhead for each page request : using \n as a delimiter precludes the use of \n within a translation. Using a serialized PHP array seems to be the least expensive solution.
I did some search about localization files, see that we can use .po file or gettext but, is there any tutorial or sample of a unique solution that will work both in javascript and in php.
I want to only maintain one localization file per language that will work with both JS and PHP languages.
Would appreciates if someone can point me to some links or samples...
I found that it is typically a sign of a questionable design when translatable text is coded inside JS functions. JS is meant to implement logic, not content. The content should be provided by PHP (typically by using a templating engine) and should be used by JS. That way you only need a localization solution for PHP.
If (exceptions always occur) you really need to translate a phrase inside a JS routine you use an ajax call to fetch the translation. This also simplifies the access to the dictionary holding the translation tokens since it is again done by PHP. The dictionary can be kept in a single place.
Yep, there is. I've successfully used gettext.js a while ago, which is operating on .json or .po files. This way, you only have to maintain one translation source. The webpage I've used this for is located here so you can check out how I've did it. Good luck!
First, try to avoid gettext if you can. It's popular and stable, but it puts some burden on the translations maintenance: you will need to change the source strings, and when this happens, gettext needs to update all the message keys, and this may mess up the existing translations. An approach with constant message keys is much easier to maintain in the long run - you will need to remember to delete the keys you don't use any more, but it's a very small burden.
You can use the same translations storage format for PHP and JavaScript. If you use a key-based approach, as I suggest, it will probably be some JSON-based format. JSON is easily accessible in both PHP and JavaScript.
There are several ready-made JavaScript libraries for JSON-based internationalization. I happen to be a developer of one such library: https://github.com/wikimedia/jquery.i18n . It should be reasonably easy to adapt it to PHP.
I am in the midst of building some web-app, and I am thinking of adding some localization to it, so people could switch easily between languages, and perhaps in the future - be able to add their own localization for the app, like Facebook's languages or uservoice.
I get it that I should have a templates, something like:
<element>[string1]</element>
and basically, that [string1] will be replaces with the correct string, but where do I store it? database? static file? isn't it "expensive" to get the string's data every time from the database? and how do I process it? using output buffer, or is there some better method that I am not aware of.
If anyone could direct me in the correct way of thinking, I will appreciate it.
There is a number of open-source translation kit systems available which should give you a better understaning of the DOs and DON'Ts (ex. pottle, poedit, virtaal).
If you decide to go your way - I'd suggest storing all the translation keys and values on the database. You'll be better off when it comes to editing, searching, getting missing translations etc.
You can generate full list of translations every 24 hours or after each new/edited translation, which would then be stored on static file in JSON or PHP serialised format. This will save you from MYSQL selects.
Another thing I would suggest is choosing a format of KEYS + KEY TRANSLATIONS. KEYS should be inserted to database on the first call to get the translation. This will lead you to "Missing translations" which is a good way of using 3rd parties or your site visitors to do the localised translations.
When I have to localize my application, I usually create a translations/ directory, and then a subdirectory for each culture. For example, I can have the following folders inside:
en-US/ - Contains the translations for users from the USA.
en-GB/ - Contains the translations for users from Great Britain.
en/ - Contains fallback, generic english translations.
Then I get the locale this way:
<?php
$default_locale = 'en';
$parts = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
$sub_parts = explode('-', $parts[0]);
if (is_dir("languages/{$parts[0]}")) {
$locale = $parts[0];
}
elseif (is_dir("languages/{$sub_parts[0]}")) {
$locale = $sub_parts[0];
}
else {
$locale = $default_locale;
}
Note that you should perform a check on the $_SERVER['HTTP_ACCEPT_LANGUAGE'] variable to avoid LFI (Local File Inclusion) attempts. Just check the locale is contained in the languages/ directory.
The usual way to do this in PHP is by storing all your strings in a PHP array, inside a PHP file.
I suggest you take a look at Gettext for PHP. The gettext functions implement an NLS (Native Language Support) API which can be used to internationalize your PHP applications.
Gettext is a de-facto standard for localization on linux/unix systems, and is widely used in PHP applications too (Wordpress, for example, uses it). For more in-depth explanation, examples, etc., take a look at the Gettext section in the PHP manual above, or you can visit the original gettext manual for a broader discussion of gettext tools, bindings, and more.
Wordpress uses gettext library, may be this would be useful to you.
I'm using Zymic, its a great hosting but it doesn't support the php gettext extension. I'm planning to buy some hosting in the future, but from now I want the simplest solution in order to replace the function of gettext, in this case I want to display different text (English, Spanish, Chinese, etc...) without modyfing the file too much (at least not having to create seaprated files for each language).
I tried something like this:
<?php
$lang = "";
switch ($lang) {
case "en":
$lang = "Hello World";
break;
case "es":
$lang = 'Hola Mundo';
break;
}
?>
<div>
<p><?php echo $lang;?></p>
</div>
When I change the $lang variable it works. I'm a PHP beginner and I can't think of a way to make it change in the browser (by clicking a link).
Or is there a better way of doing this?
I would say Zend_translate is the very best bet for internationalization these days. It's even better than gettext. See this SO Question for a number of arguments. This question was how I myself learned of Zend_translate.
It is a bit much for the simple task you show in your question, and it may be take a bit of work to get used to it in the beginning, but the Zend components promise very good solutions to all kinds of internationalization issues - which are more than just translating words. There are also different numbering formats, time formats, currency formats, time zones... all to be taken care of when internationalizing an application.
It doesn't require any specific extensions, and you can use parts of the Zend Framework as a simple library, there is no need to adhere to a specific application structure or anything.
This must be one of the oldest answers I've ever supplied, but...
PHP-gettext at https://launchpad.net/php-gettext is by far the simplest workhose as gettext replacement.
I've used in some projects I've had troubles getting gettext working with PHP.
Recently I am working into the ability of translating a PHP web application from one language to another. Well, most of those I read involves having language files, then display the selected one like this:
en.lang.php:
<?php
$_TEXT = array();
$_TEXT['welcome'] = 'Welcome to My Application';
?>
fr.lang.php: // french (i translated that with Google =x)
<?php
$_TEXT = array();
$_TEXT['welcome'] = 'Bienvenue sur mon application Web';
?>
I would like to ask if there's any better workflow or algorithm than this? Because value may be inserted into the text and so on - pretty hairy situation. Any help thanks!
Also to note that: this application must work cross-platform (or I should say platform-independent) as such no additional extensions are required based from PHP 4.4.2
I would advise using gettext, it'll make your life so much simpler...
The gettext functions implement an NLS
(Native Language Support) API which
can be used to internationalize your
PHP applications. Please see the
gettext documentation for your system
for a thorough explanation of these
functions or view the docs at ยป
http://www.gnu.org/software/gettext/manual/gettext.html.
Checkout PHP's gettext: http://www.php.net/manual/en/intro.gettext.php
If you want to roll your own simple solution, I define a function, __($native, $var1, $var2, ...), that takes the native string and performs the translation + variable substitution for you. The actual implementation of __ (two underscores) will depend on you, but typically $native is the key in your array above and it uses sprintf to substitute.
That s actually called Internationalization or localization.
If you are using php, i d recommend you to use smarty. You can do the same thing as you do with Java. and smarty has gettext plugin. you actually dont even have to mess with gettext, you can do it way easier than that.
http://www.smarty.net/
or perhaps you can check out the pear libraries i ve seen packages for localization.
http://pear.php.net/packages.php?catpid=28
gettext, as suggested by several fellow SOers is an excellent solution. It's not php specific, it's quite popular and as such several tools to simplify translation are available.
And last but not least, keeping the text in your default language in the source is many times easier to work with than having to remember the constant values for texts.