I have managed to make my URL i18n compliant using Zend_Controller_Router.
Ie:
en/user/login becomes fr/utilisateur/connexion and both URLs go to the same controller/action.
The problem I am facing is the following
I have a language switcher that is displayed as follow :
Français
English
Italiano
etc.
The currently active language doesn't have an anchor tag, but all others do.
For the languages that have an anchor on them I am building the URL and I want them to be translated in their specific languages.
Currently if I am in French all the urls get builded in french, even if I set the #local key as a param in the URL view helper (tried "#locale" => 'en', "#locale" => new Zend_Locale('en'))
en/utilisateur/connexion
it/utilisateur/connexion
instead of
en/user/login
it/utente/collegamento
because the locale used while building the URL is the one that is defined application wide.
EDIT
I digged a bit deeper in my issue an I found that only the current locale add its resources loaded, which mean I can't get route in the proper language for the route to be built in the right language
My new issue is : how do I load multiple language translation resources?
(I am planning to implement cache in the far future (near release), so I might get better performances)
Hope this helps re the new issue.
"My new issue is : how do I load multiple language translation resources?"
Just a quick caveat to say I didn't write the code below, it was taken from a example app put together by the guys at Zend however it might help to have it broken down like this.
Their approach for the example app was using a csv file containing translations and using your config file (the default one in a new project being application.ini) to specify the path to all your language translation resources.
like this:
;; Languages
language.file.en = APPLICATION_PATH "/../language/en/translate.csv"
language.file.fr = APPLICATION_PATH "/../language/fr/translate.csv"
language.file.de = APPLICATION_PATH "/../language/de/translate.csv"
language.file.es = APPLICATION_PATH "/../language/es/translate.csv"
language.name.zz = Language
language.name.en = English
language.name.fr = Français
language.name.de = Deutsche
language.name.es = Español
And in each csv file, if you are using something like Excel or Open Office to create it, column A would be the original language and column B the translation.
As an example where English is the original language and a Spanish translation is required:
A B
login entrar
logout salir
You could do that for all the words/phrases you want to translate.
If a translation isn't found then the default original word is used.
Your main application bootstrap could have something like this:
protected function _initLanguage()
{
$options = $this->getOptions();
Zend_Registry::set('language',$options['language']);
$langSess = new Zend_Session_Namespace('language');
if (!isset($langSess->translate)) {
$translate = new Zend_Translate('csv', $options['language']['file']['en']);
$langSess->translate = $translate;
}
if (!isset($langSess->locale)) {
$langSess->locale = 'en';
}
Zend_Locale::setDefault($langSess->locale);
}
As the translate object is held in the session you can use it in any of your views etc using something like:
$langSess = new Zend_Session_Namespace('language');
$translate = $langSess->translate;
and:
<?php echo $translate->_('login') ?>
where you want something to be translated on selecting an alternative language. In the example above the word login would appear when English is selected and entrar when Spanish is selected.
There's loads more to Zend_Translate than this and several ways to implement it so I'm not saying this is the best way by any means.
If it helps or if I can give you more info let me know.
Cheers,
Dave
Related
In my codeigniter webapp, I'm using multi language site. Default and in english like these:
www.xxx.com (default)
www.xxx.com/en (english)
And I have a controller where I want to re-route specific calls say potato and tomato to vegie like these:
www.xxx.com/potato/param => www.xxx.com/vegie/param
www.xxx.com/tomato/param => www.xxx.com/vegie/param
So far, I have managed to reroute with default language url using like this in my route.php:
$route['potato/(.+)$'] = 'vegie/$1';
$route['tomato/(.+)$'] = 'vegie/$1';
But I doesn't work for the english site. I did like this, and not working:
$route['en/potato/(.+)$'] = 'en/vegie/$1';
$route['en/tomato/(.+)$'] = 'en/vegie/$1';
Anyone can help me for this? Thanks.
First, create new function to manage the english version, ex: function vegie_en()
then route to it
$route['en/potato/(:any)'] = 'vegie_en/$1';
I have found the problem. I have this in my route.php which makes it rerouting wrongly if there's prefix en/:
$route['en/(.+)$'] = '$1';
I moved this to the end of the route.php and it working very fine now.
I had faced same problem in my project. I fixed it by removing the 'en' and put $2 as for dynamic value.
So in your case, this will work.Please try this given below code.
$route['en/potato/(.+)$'] = 'vegie/$2';
$route['en/tomato/(.+)$'] = 'vegie/$2';
This question already has answers here:
Create a webpage with Multilanguage in PHP
(10 answers)
Closed 9 years ago.
Alright, so I'm forced to create a multi-language support site in 4 languages (Greek, French, English and German). I have some ideas on how to set it up, although I would like a second opinion on this.
The first option is to include the file based on the user's settings.
/*
------------------
Language: English in ENGLISH.PHP
------------------
*/
$lang['TITLE'] = 'My website page title';
$lang['HOME'] = 'Home';
/*
------------------
Language: French in FRENCH.PHP
------------------
*/
$lang['TITLE'] = 'Titre site-web';
$lang['HOME'] = 'Accueil';
The file would be included accordingly: include_once 'ENGLISH.PHP'; etc.
The other option is to create one general file, but have the language output in an array:
$lang = array("en"=> array("TITLE"=>'My website page title',
"HOME" =>'Home'),
"fr"=> array("TITLE"=>'Titre site-web',
"HOME" =>'Accueil'));
$set = $USER_INFO->langPref(); // output: en, fr, gr, de
echo $lang[$set]['TITLE'];
The second option seems easier to manage, but I'm not sure if there are any drawbacks to this method...
Any opinions?
By the way, I was planning on translating everything myself.
Don't waste your time, use a framework, Symfony2 for example has a excellent internationalization component:
http://symfony.com/doc/current/components/intl.html
or CakePHP, even easier =)
http://book.cakephp.org/2.0/en/core-libraries/internationalization-and-localization.html
but...if you really...really want to do from scratch =) I recommend you to use something like .po files, here you are some article that could help; http://www.icanlocalize.com/site/tutorials/how-to-translate-with-gettext-po-and-pot-files/
I strongly recommend the use of a framework or even a CMS has this functionality built in...
I hope this can help.
You can used .ini to store language:
set = $USER_INFO->langPref();
if(file_exists("PATH_TO_FOLDER_LANGUAGE/".$set.'.ini')){
$arrLanguage= parse_ini_file("PATH_TO_FOLDER_LANGUAGE/".$set.'.ini');
}else{
$arrLanguage = array();
echo "Language file not found";
}
print_r($arrLanguage);
in ini file, it will be same:
TITLE=Titre site-web
HOME=Accueil'
read more about init file at here: http://en.wikipedia.org/wiki/INI_file
Hope it can help you!
i have an issue that is going to destroy my mind ... i am not a PHP developer so i can not find any way to solve it...
I am using K2 (v 2.6.2 updated from 2.5.7) for CCK (with alotof custom templates) and Joomfish (2.1.7) deployed on a Joomla 1.5.26 installation.
I was using the following code (in my templates) in order to fetch my individual k2 extra fields by name (K2 2.5.7):
$extraFld = array();
if ( $this->item->extra_fields ) {
foreach ( $this->item->extra_fields as $key=>$extraField ) {
$extraFld[ $extraField->name ] = $extraField->value;
}
}
and then i was fetching it like this:
echo "<li class=\"dinning-cuisine\"><span>" . JText::_('Cuisine') . "</span><br />" . $extraFld['Cuisine'] . "</li>\n";
But since version 2.6.2 there is the option to directly fetch an extra field name & val:
$this->item-extraFields->ALIASNAME->name
$this->item-extraFields->ALIASNAME->value
as described in K2 2.6.2 What is new documentation.
The problem is the following:
I have a bi-lingual site in Greek (default) and English locales.
I create an extra field in Default locale "Πεδίο 1" with alias name 'field1'
If i try to translate it the only option i have is to translate its name to lets say 'Extra Field 1' (different than its alias) ...
Then in my custom template if i try to fetch it like:
$this->item->extraFields->field1->value
only the Greek locale works. In English locale i receive a NULL value!
Any relevant experiences and solutions ?
Try doing this:
String:
JText::_('CUISINE') //should always be Capital letters
Translation (language file):
CUISINE=Cuisine
I'm not sure which file you are using to translate the string, however seeing as you are adding this code to your template index.php, add the translation string to en-GB.tpl_tamplatename.ini
After quite alot of tests i think that in a multilingual web site, retrieving individual extra field values using their alias name does not work. At least not for Joomla 1.5 ...
The code supposed to be working is:
$this->item-extraFields->ALIASNAME->value
I have a web site with default language 'Greek' and secondary language 'English'.
I have an extra field named in Greek 'Πεδίο 1' with Alias 'field1'.
I have translated this extra field (using Joomfish) in English to 'Field 1'...
If i try to fetch its value using:
$this->item-extraFields->field1->value
the code is working only for default language 'Greek' BUT NOT for English.
I have been using zend translate to translate the site content but what about the urls? How could I translate it?
Ex.:
localhost/app/contact (English)
localhost/app/contato (Portuguese)
If you are indeed using Zend Translate you should be able to use translations in your router like:
routes.someroute.route = "/:langparam/#translateme"
routes.someroute.defaults.module = public
routes.someroute.defaults.controller = page
routes.someroute.defaults.action = show
If your translation source contains 'translateme' it wil be translated, if not the router will use 'translateme' as value.
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?
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.
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.
How should you implement it? Like Zend_Translate.
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.
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.