views:

1414

answers:

5

I'm posting this question on it's own as I found post one which lacks full explanation or the best way to do it.

Should I use a language file to name items like:

$first_name= 'name'; $last_name = 'last_name';

and then include this file depending on selection?

I have an app which I need to have in two languages.

Will like something in this lines:

http://www.myapp.com/?lang=en http://www.myapp.com/?lang=es

Should I use a constants file for this purpose?

constants.php

define('OPERATION_NOT_ALLOWED_EN', 'This operation is not allowed!');

define('OPERATION_NOT_ALLOWED_ES', 'This operation is not allowed!');

What is the recommended way of accomplishing this?

A: 

I would use locale-specific files with constants, eg:

locale_en.php:

define('GREETING', "Welcome to Widgets Inc');

and

locale_de.php:

define('GREETING', 'Wir begruessen Sie zu Widgets Inc');

in your setup you detect the locale and do:

if ($locale == 'en') {
  require 'locale_en.php';
} else if ($locale == 'de') {
  require 'locale_de.php';
}

This gives you the benefit of constants and makes localization reasonably transparent to your application in that you don't have to do if ($locale ... all over the place. If anything is locale-specific, just put it in the locale files.

If you want to add a locale file just copy an existing one and change all the references rather than trawling your codebase for them.

You can also put code in these files like correctly formatting numbers and dates for these locales (including the right names in each language but also the use of commas, quotes, periods and so on), currency conversions and displays, etc.

cletus
Do I detect the language with GET? Something like: $locale = $_GET['lang']; THAT will read of the uri?
Codex73
There are issues with auto-detecting language. I would just default to English (or whatever is appropriate for the main site audience) and then have little flags ton the page to change it, which will set it in the cookie.
cletus
+2  A: 

You can follow in the footsteps of phpBB - they use a $lang[] array with code that looks like:

$lang['Next'] = 'Next';
$lang['Previous'] = 'Previous';
$lang['Goto_page'] = 'Goto page';
$lang['Joined'] = 'Joined';
$lang['IP_Address'] = 'IP Address';

$lang['Select_forum'] = 'Select a forum';
$lang['View_latest_post'] = 'View latest post';
$lang['View_newest_post'] = 'View newest post';
$lang['Page_of'] = 'Page <b>%d</b> of <b>%d</b>'; // Replaces with: Page 1 of 2 for example

$lang['ICQ'] = 'ICQ Number';
$lang['AIM'] = 'AIM Address';
$lang['MSNM'] = 'MSN Messenger';
$lang['YIM'] = 'Yahoo Messenger';

It is of course included from a file specified in the user's settings, but you'd be fine with your suggestion of ?lang=en in the query string accessing something similar to a constants.php file.

You might want to name the file lang_en.php or something similar for clarity.

John Rasch
I recommend this method as well.
jerebear
+1  A: 

That will work for strings like you gave in your example. But there are other complications. For example, do you want to format dates in the appropriate format for the locale (es vs en?). How about formatting of numbers and currencies? Also, you might have "dynamic" messages: "You have $x messages in your inbox". Where you want to pass variables. Check out some of the php localization libraries. Here is an online tutorial: http://www.devx.com/webdev/Article/38732.

Also look at the framework you are using. Many of them have localization support.

Dave
A: 

There are free 3rd party controls to do this using an ISO standard XML file (I wrote a database utility to create, edit & export into this format).

The other answers are very manual and involve more work than using this control does.

The control you need is found at: http://ezcomponents.org/docs/api/trunk/introduction_Translation.html

After the eZ Components are installed on the server, you need to retrieve the base control required for all eZ Components

require_once "ezc/Base/base.php";
/**
 * __autoload()
 *
 * @param mixed $className
 * @return
 */
function __autoload( $className )
{
    ezcBase::autoload( $className );
}

Then you must define where the XML language file is located (see: ISO639-2, ISO3166, and Qt Linguist)

$config["language_code"] = "en_us"; // as defined by ISO639-2 and ISO3166

// grab our translation XML file
$backend = new ezcTranslationTsBackend( dirname( __FILE__ ). '/translations' );
$backend -> setOptions( array( 'format' => $config["language_code"].'.xml' ) );

// create a manager object
$manager = new ezcTranslationManager( $backend );

$language = $manager->getContext( $config["language_code"], 'strings' );

now you can grab strings by simply calling the following function

getTranslation( "SOME_KEY" );

and to retrieve phrases that have parameters use the following syntax, please note the relation between [KEYWORD] and "keyword" is intentional and recommended

getTranslation( "FIND_[KEYWORD]_BY_[TYPE]", array("keyword" => $keyword, "type" => $type ) );

an example of a TS XML file is (should be called en_US.xml)

<!DOCTYPE TS>
<TS>
<context>
    <name>strings</name>
    <message>
        <source>ZONE_TYPE</source>
        <translation>Zone Type</translation>
    </message>
    <message>
        <source>ZONE_TOOL</source>
        <translation>Zone Tool</translation>
    </message>
    <message>
        <source>HELLO_[NAME]_WELCOME_TO</source>
        <translation>Hello, %name, welcome to Webfood Admin</translation>
    </message>
    <message>
        <source>YOUR_ADMINISTRATIVE_SESSION_HAS</source>
        <translation>Your administrative session has timed out. Please login again.</translation>
    </message>
</context>
</TS>

I would simply have a setting, in your PHP sessions, that stores the language used, perhaps ask the user before or after they log in which language they want, and store it to their user table if you have accounts. There's no reason to keep sending a URL value over and over, that's a bad idea.

TravisO
Ty, looking forward for the link.
Codex73
+1  A: 

How should you implement it? Like Zend_Translate.

vartec