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'
Related
I faced this problem several times while building websites.
I will explain the using PHP and Laravel as an example but this problem is a common amoung multiple platforms.
This was already addressed in a few questions (post1, post2,post3, post4 and some others) but the posts didn't really get a good answer.
The question is: What is the best way of structuring translated content inside of language files?
I'm currently using Laravel (I'm not mentioning the version because both Laravel 4 and Laravel 5 have similar localisation functionalities, at least similar enough for the purpouses of this topic).
The localisation structures the content accross language files (en, es,de, fr...) inside which there can be multiple .php files that contain a return statement that returns a multi-level dictionary structure.
/lang
/en
messages.php
/es
messages.php
and the files contain something like this:
<?php
return [
'example1' => 'example message for value exaple-key',
'example2' => [
'sub-example' => 'example message for example1.sub.example',
],
];
and calling of this is done by doing something like this:
//Laravel 5
trans('messages.example1'); //outputs 'example message for value exaple-key'
trans('messages.example2.sub-example'); //outputs 'example message for example1.sub.example'
//Laravel 4
Lang::get('messages.example1'); //outputs 'example message for value exaple-key'
Lang::get('messages.example2.sub-example'); //outputs 'example message for example1.sub.example'
A few methods of grouping come to mind:
by website content
example: homepage.php, page1.php, page2.php...
by logical domain:
example: auth.php, validation.php, pagination.php...
by html:
example: buttons.php, popup_messages.php, form_data.php...
by straight traslation:
example: simple_words.php, phrases.php... and than contain content like 'password-to-short' => 'your password is to long'
Some hybrid/combination of the ones mentioned before
All of these have some obvious benefits and drawbacks and I won't try to go int that but the 5th option is most likely the best solution but there's still the problem of where to draw the line to get minimal duplication of phrases and content.
Annother problem is how to solve the problem of uppercase first characters in some cases and lowercase in other cases as well as punctuation characters at the ends.
I did reaserch regarding this problem but there are no definitive guidelines and/or good examples available to learn from.
All opinions are welcome.
I tend to group functionality in my Laravel apps into self-contained ‘components’. For example, I’ve been working on email campaign functionality for an application recently so put the service provider class, models, service classes in a folder at app/Email.
Bearing this in mind, I organise my translations in a similar fashion. So even though on this project we’re not translating strings, if we were I would create a resources/assets/lang/en/email.php file, and put translated strings for the email component in there.
So in another project, my directory structure might look like this:
/resources
/lang
/en
auth.php
email.php
events.php
news.php
pagination.php
passwords.php
validation.php
Hope this helps.
In my experience there is no reason to have different groups other than trying to use your translations somewhere else. I usually put all my project messages in a group named app and for each of my shared libraries I use a separate group name (because I might use them in other projects).
An example of a a failure login message in my website would be
trans('app.username_and_password_do_not_match')
and if it's in a third party library named Auth it would be
trans('auth.username_and_password_do_not_match')
And remember to write the full message as your message key instead of using short names (like app.login.fail). this way you don't need to check the website content for every translation.
I didn't fully understand your last problem so you might want to clarify it a bit.
I would go with option #4, so you'd have something like this:
/lang/
/en
messages.php
words.php
/fr
message.php
words.php
/de
messages.php
words.php
This does a few things:
It segments out everything very clearly. You know which language to find where. And you know what's in the file associated with the language.
The above makes maintenance easier in the future because you can find stuff.
It gives you files, by language, that can be translated separately.
It puts all the message in one clearly defined place.
One thing to note, is that if your app gets REALLY big and REALLY international, you may want to use ISO language codes instead. For example, european Portugese (pt_PT) and Brazilian Portugese are different and with a global audience you'd probably want to cover both.
This is the scenario:
I have a website that I'll translate and eventually apply a good SEO on it.
Which method is best for translate the content (menu links, about 10 articles, alt tags, title tags, meta tags, html lang, etc) while being easely indexed by Google, Bing, Yandex and other search engines?
My first idea is to use a translate php function that consists of arrays made by myself (I have a prototyope of it already) that takes the content and displays it in the user's language.
Is this the right path? the problem here is that I wanted to be sure to have a dynamic system that allows me to add a new language in the future.
Maybe MySql is the right choice?
The website doesn't use a cms, I made it by myself with php though I have no problem to rely on MySql if I need to.
Thank you in advance :)
You've basically got 3 choices and there are pros and cons to each:
1: as Dainis Abols suggests, chuck it in the database - depending on how your server is set up this could be the slowest, most system heavy route (it's all relative though, it's unlikely to make any difference unless you're getting millions of view an hour).
2: use PHP library files; I tend to use library files for small, single items like field labels (forename, surname etc) and store larger things like CMS-managed HTML in the database... this reduces the database calls but adds a small overhead for each dictionary you load into a script <?php $this->page->dictionary->product = Dictionary::load("product"); ?> sort of thing.
3: finally, I personally think it's worth taking a look at PHP's implementation of gettext though you'll need something like poedit to maintain the PO (compressed translation files). This gives you the ability to very rapidly maintain translations as you just enter the text in your PHP document by wrapping it in a simple underscore function:
e.g. <?= _("Hello World"); ?>
You then maintain the translations in compressed PO files - it's very efficient (potentially faster than doing it with native PHP files) however it does have some drawbacks when it comes to the nuances of natural language.
As an example, if you have a field label "title" <?= _("Title"); ?> then all instances of _("Title") will be translated in the same way.
This means you can't use "Title" as both a form label for a person's title and as the title of a book; for instance, in German, you may want to use Anrede for one "Title" and Titel for the other.
Although, to really use gettext you'd probably need to be running your own server - it can require an Apache reboot when you change the PO files :\
As for Search Engines they read the output from your code so it doesn't really make a lot of difference which method you use to perform the translations but ideally you may want to keep the URLs RESTful so whether you're including PHP dictionaries, calling the database or using gettext (or changing your mind from one to another later), you'll be able to map the language to the URL with something like http://www.mysite.com/en_gb/widgets so you can change how the program works without changing the URLs.
Store all texts inside a db and apply another field for language:
+----+---------+---------+
| id | text_en | text_de |
+----+---------+---------+
| 1 | English | Deutch |
+----+---------+---------+
Now, when user switches languages, just use the field for that language:
$lang = 'en';
$query = "SELECT text_".$lang." FROM texts WHERE id = 1";
Something like that. So, all your client side texts will be stored inside the db at all times. So your output will be like:
<div id="header"><?=get_db_text_for_id(1)?></div>
Of course, you need precautions and some more field, but thats the general idea.
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 am working on a website and the requirement is to make it in two languages i.e. icelandic and english.
just like facebook and other google, if a user selects a language, then the site is translated in that language.
I am not allowed to use google translator.
Any other way to do this in Php
Thanks in advance
Well, I never did it, but i did think about it :), for me i have to do something like this from scratch,
First, do not echo your String that will be displayed to your clients hardcoded, create a dictionary, this dictionary can be in any format, be it php file, xml file, json. You can also extend the functionality by adding Database in it. The main idea is to create a dictionary having all your messages that will be displayed to the user in all the languages you want to display it
consider if you do it using normal PHP FIle, use OOP built class say known as Message, then as attribute to the class add the several languages that you have to use and also some setters and getters
e.g.
Message
{
english;
french;
.....
}
then in PHP, when you echo your messages, try to get the language you want to use, and then
do something like this
echo message.getEnglishMessage();
Look, I've been very generic, now decide on the type of file that you'll use and build the dictionary
Hopes it helps :-)
I use an es.php (spanish not sure what icelandic is) and build all of the mod_rewrite off that. You treat it exactly same as you would if it were the index.php for english. For inputing data into the database have a column for language. All of your queries that call data will then have the language as a condition.
The "gettext" is the way you can go with but if you and your client are in nice understanding ask him to provide the data in language other than english as well and then in DB table there will be a column 'language' in which 'ic' or 'en' flag will be the data, and during fetching the data anywhere, according to language your sql query will contain the language as a where condition with desired flag as its value.
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