I'm trying to rewrite asp.net mvc application to codeigniter.
Basically codeigniter follow mvc pattern so it's pretty much ok. Now I'm stuck at localization.
I do not want to change url, in order that /Company/About remains the same in english and german. Inside view I had in asp.net Views/Index.cshtml as default for german and Views/Index.en.US.cshtml for english localized page.
I will describe scenario which works perfect on my asp website.
User clicks on country flag
Based on 1. step value cookie is populated with country value
Helper load desired thred into current thread
Views are localized
How can I apply this approach to codeigniter, or similar at least?
Thanks
I think it will be not a good idea to have separate files for each language. You can do it easily using some other techniques, which are easy to implement.
While working on one of my CI project, i need to make it to support multiple languages. As i worked in other multilingual systems like Prestashop, so i borrowed ideas from there and implemented it in my CI project.
I have implemented it as followed:
1) I am storing words in language files. Each language has its single file named as language ISO code, like for english its name is en.php In this language file, words are stored as file_name_md5(of the word) in array like below for Hello World in view file hello.php .
$_lang = array(
'hello_b10a8db164e0754105b7a99be72e3fe5' => 'hallo Welt',
...
...
...
)
The key of the $_lang associative array is the world appended with file name, to be translated, and the value is the translation.
Storing words and fetching the words into / from these language files, are handled by the Translation library I created.
2) All my static text in views files are written in english. I created helper function for it called "l" , small L . Lets say i want Hello world to in my view (say hello.php) and should be translated into multiple languages. So in my view i write it like
<?=$this->l('Hello World...', 'hello')?>
3) Now the l helper function perform small operation on the arguments passed to it. It takes md5 of the world and append it with the file name as you can see above. Then it calls a member function of my Translation library, which looks into the $_lang array to find that match. If it finds the match, it returns the translation. If no translation is found for that word, then the l helper function returns the original text back.
4) I have created my own controller library from which all my controllers are extended. To preserve CI features, my parent controllers are extended from default CI controller. In my parent controller, i load the language files according to the user language. This way the $_lang array is available for the Translation library to look into for the words.
5) In my admin side, i have created a translation system, which reads all my View files for a specific pattern like the below one
<?=$this->l('Hello World...', 'hello')?>
The code generate a form in which a text field is created for each word. The text field name is the same as the $_lang array keys, like filename_md5_of_word . The text field label is the original word in this case "Hello World...". And the translation has to be written to the text field.
On saving, the translations are stored in to specific language file for that particular language selected for translation.
Using this method, you will be able to add as many languages as you like in future, without creating view files for each language, so it is flexible.
I hope i have explained enough so you can take the idea of how easily you can implement translation system, and avoid separate view files for each language.
If you have any questions, feel free to contact me here.
Thank you
Related
As I've started building a project, there will be quite a few entries in the .po translation file. I use Poedit to build these.
My question is, what is the best practice for entries within this file? I was thinking, instead of referencing entries such as:
echo _('This is an entry.');
I was thinking of organizing them like:
echo _('error_pwd');
echo _('error_user_taken');
Which, once ran through the translation file, would output something like:
Password incorrect. Please try again.
Username is already taken. Please try another.
So, all my translations can be organized by type, such as error_, msg_, status_, tip_, etc.
Has anyone seen it done this way, or have any suggestions on a more organized method?
In fact it doesn't matter!
It's just up to you.
However, I advise you do not split translations in sections.
No there's any benefit in doing so. Actually, the most projects use the one file approach for all msgid entries.
Like django, see.
Of course, If you still want split translation by sections, might you want take a look on Domains:
From PHP doc:
This function (textdomain()) sets the domain to search within when calls are made to
gettext(), usually the named after an application.
Also, as earlier said, the advantage when using msgid as a real phrase ou word (instead underline or dotted notation key) is that it stays as default message if no there's a translation for entry.
And here goes some helpful links:
Django Porject - i18n, Definition
PHP textdomain function
What is bindtextdomain, textdomain in gettext?
How to determine which catalog to be used
This is a standard approach for other framework, e.g. Symfony/Laravel:
trans('error.validation');
But it has a downfall, if you forget to translate one phrase on your site it will appear like the keyword 'error.validation'
I have a site; I need to develop to support multiple languages, for example en, tr, ar, sp, etc.
But the problem is , what is the best way to do it with Codeigniter?
I have a controller ( SITE ). I have a lot of functions LIKE ( hotel , city , page , blog )
I want to before this method add a segment ( language ). This is old links
http://example.com/hotel/mariot
http://example.com/hotel/hilton
http://example.com/city/london
http://example.com/city/paris
...
..
and I want the links to be like this
http://example.com/en/hotel/mariot
http://example.com/ar/hotel/mariot
http://example.com/sp/hotel/mariot
http://example.com/tr/hotel/mariot
http://example.com/en/city/london
http://example.com/ar/city/paris
....
..
sometimes thinking every language have a controller but it is possible...
What is the best way to change all links to support the languages?
I'm sorry If my question is not clear, this is my English.
The right way, is using routes.php look for it inside (application/config/routes.php)
You can use regex expressions for your specific problem.
here is the manual: http://ellislab.com/codeigniter/user-guide/general/routing.html
if you want your links to be like this
http://example.com/en/something
then you might need to have subdomain or folder in your project called en. but yet this is not the perfect solution.
what you have to do is to make your text output assigned into variables which takes their values from an xml file. like if you have some text called "your room number is: 0" and this value is hard coded HTML then you should put it in en.xml file under some tag and get it from the xml file which is requested by the user according to the required lang.
you might can do the previous solution in all languages but you have to consider that Arabic language is RTL language so just consider that in your css. But generally you can use xml files to control the languages.
hope that is what you needed.
i need to translate my site in multiple languages. i was thinking to use a database called language and put the translation there.
database : translation
tables: language
column: id, english, french, german, italian, spanish
or i was thinking about a php solution like:
english.php
french.php
german.php
italian.php
spanish.php
so you simply include the file you need.
now, i can see pros and cons for both, what i want to know is what is consider the standard in the industry to do something like this?
You can use gettext, this function is proposed for this feature, not a "standard" but fast enough.
The second options in the use of a PHP file with a big array (really big, for each string), this is the most common solution.
To the database content (the big problem here, don't forget), if all your content must have the translation, one column for each language, otherwise use a flag of language for each line on database.
There is no industry standard. I have seen (and implemented) solutions using flat files, XML, PHP code, a database, and gettext files to store the localized strings. It's a matter of what is more suitable for you.
My go-to method for PHP is simply files containing arrays of strings, for example
en.php
return array (
'How are you?' => 'How are you?',
'Goodbye' => 'Goodbye',
);
de.php
return array (
'How are you?' => 'Wie gehts?',
'Goodbye' => 'Auf wiedersehen',
);
This can be integrated into an application with reasonable granularity (there can be many such files, e.g. one for each component) and control (you can easily fall back to any other language if you don't find a string) and it is also very convenient to modify without need for special tools.
My favorite PHP framework (Yii) and a giant open source project I have worked on (Moodle) also use this approach.
Noone of the two solutions seems great to me. You should think in the long run when you think a solution.
What if you choose to translate your website in other languages different from those you thought as russian or chinese? In the first case you have to add more and more columns, in the second you've to create more and more file. Another cons is what if you translate a page in italian and spanish but not yet in french?
I think that a good thing is to have a database based solution and a main language. Now you can do something like this:
Create a table 'page' (id, title, ...) where you'll store the page in the main language and where you'll have the info of the translated page too
Create a table 'translation' (idsource, idtranslation, language)
Everytime check the available translations and give those to the users
In database localization you have four main strategies. Each has particular advantages and disadvantages. For the long term I would definitely recommend cloning. You can see the four methods at the link below:
http://www.sisulizer.com/localization/software/server-desktop-database.shtml
There are two main ideas you want to be sure to be implementing. The first, be sure you are integrating some form of translation memory. Your language vendor should be instructing you on how to do this and probably doing it for you.
The second, for each additional language you target, your data will get at least 2x more complex. Keep this in mind as you move forward. Not only your data, but your file sets, management, etc.
Hope that helps. Let me know if you have further questions.
Russell
I am currently making a web page with dynamic content from a database (a restaurant menu) storing item names, prices, yada yada. The restaurant usually caters to English and Japanese. I have stored the titles of the items in the database as English and Japanese, however when it comes to the type of the item, for example, Type: Drink, Type of Drink: Coffee I can obviously store the type of item alongside the item in the database, but it hardly seems worth it to store it twice as two different languages in the the database which would also make the form to add a new item a pain.
What is the best way to go about translating those little tiny pieces of information, like "Coffee", "Wine", "Click Here", "Menus", and using them on the page?
You can use gettext extension for translation static or predefined info on web page.
See manual http://php.net/manual/en/book.gettext.php
Example http://mel.melaxis.com/devblog/2005/08/06/localizing-php-web-sites-using-gettext/
I would store it in both languages, it makes the most sense to me. I don't see why you would go and do a request to your translation system each time you want to show any page in your menu.
If you are using an automatic translation system that you really trust, one thing that you could do is use it when adding a new item to make a suggestion. So, after the user enters the word in English on the form, automatically attempt to translate that into Japanese and put it in the Japanese field. If the user is satisfied with the translation, that's it for that task, otherwise he/she inputs with a better one.
if you are using any phph5 based framework , major framework have localization support like zend has Zend_Locale
if you want your own translation dictionary , keep key value pair data in database table and memcached between application and DB , so static data will be cached for particular expiry time and data base load will be get decreased and fast retrieval of data
My current approach has been to use to _remap function provided by codeigniter to get the URI segment in order to check if the language is "en" or "np"
Here is a sample:
function _remap($url_title){
$this->_identify_language($this->uri->segment(1));
$data ['sub_categories'] = $this->category_model->get_category_list_by_url($url_title)->result_array();
$data ['news'] = $this->news_model->get_news_list_by_url($url_title)->result_array();
$data ['url_title'] = $url_title;
$this->_render_front_view('main',$data);
}
I am using this technique on every controller. Which is well not very efficient.
I wanted to ask if using sessions to store language codes would be better or is my current technique good enough?
Are there any other ways i can do this multi-lingual thing?
Of course my database is currently shaped for 2 lanaguages and i have seperated the fields. e.g:- title_en, title_np. these are echoed according to the language field used.
Lots of parts to this.
Your URL's do not really need to be /en/ and /fr/ unless you want it to be used for Google Analytics. Spidering doesn't make a lot of difference. Accept-Language headers can be just as reliable.
Globally parse this URL segment. You can use this method or the Accept-Language, but either way you need a hook, a MY_Controller or extend the Lang class.
Think about if you want the different languages to be totally seperate. For example, if I have an English page not translated to French, and the French page does not exist, should it show the English page or 404? You can either store the lang = fr in the database and take the value from a constant set in the hook/MY_Controller/etc.
WHERE lang = CURRENT_LANGUAGE
Structure your DB. title_en title_fr is one method, but it soon because unmanagable with lots of languages. Have a "pages" and "page_content" table, so that all generic information is in one table then all language specific (title, content, meta, etc) is in the page_conten table, which has a lang field.
There are a million ways to do all of this, but there is lots more to think about than just the URL. My favourite
I have been using this internationalization library for codeigniter and I find it suits my needs pretty well.
It extends the Lang class, and then in the constructor it parses the URI to figure out which language to use. So it is just loaded before you use any language files. You don't need to add any code to your controllers. It simply changes the setting in the language object. So you can retrieve the current language the same as you normally would:
$this->lang->lang();
If you have 500 news and 2 languages, changing url prefix in root will give you 1000 links, lets say "/en/hello-world" and "/np/hello-world" will have identical content and possibly the same title, which can be bad from SEO aspect. I would use session or cookies to store preferences, to preserve link juice.