From my previous questions about gettext, one of the biggest benefits of using PHP's gettext extension instead of other methods of language translation was that it is super easy to have other people make translation files with a program called Poedit.
Now I have gettext working in my app but I have not made any translation files yet, I found a demo file on the net and tested with it to conform my app works with gettext though.
Now I played around with poedit a little bit and I might be wrong, hopefully someone can clarify some issues.
As far as I can tell poedit reads through your php code and finds all availabale spots to do a translation, is this correct?
If the above is correct, then how do you have a human translator translate with poedit without having access to your app?
Or in simple terms is it possible to make a translation file with poedit without it having access to your php code?
Note that I have never used poedit myself, so this might not be totally accurate...
An interesting article that you might first read, for some information : Localizing a WordPress Plugin Using poEdit. It's WordPress, which means PHP -- so the basic ideas should be OK for your application.
Basically:
you first extract all the strings from the PHP source code
by telling poedit how your translation function is called
this should answer your 1)
then, you do translation
working with/on the .po file
And I'm guessing you can distribute this .po file to your translators, who can then translate the strings it contains
and, finally, you use the .po file to generate the .mo file that will be used in your application.
This other article, about WordPress too, seems to indicate that I'm guessing right : User:Skippy/Creating POT Files -- especially, this sentence :
Make the .po file available for
download (or optionally include it in
the plugin archive). Translators will
use this file to construct a .mo file,
which will be used by the
load_plugin_textdomain() function.
(Obviously, the function name you'll be using in your application will not be the same as the one in WordPress -- still, the idea is there).
No, poEdit doesn't read all your sources. You use the gettext utility "xgettext" to do that.
Basically, xgettext will produce a .po file.
Your translators will use POEdit to work on that .po file.
When the translater is done, you'll compile the .po into an .mo, which you app will use to look up translations.
If you have gettext installed on some unixy system, try "info gettext" in bash.
PoEdit actually uses xgettext, which you can set up on the Settings/Parsers tab correctly.
You should distribute a .pot file by the way, which is a .po template. So translators can translate it, set the language, the translator team, etc.
Unfortunately, I cannot see an option to create .pot file from source, but poedit can read then (of course, it's the same as .po).
After creating their own .po, you can have the .mo!
Related
I have a multi language website written in CakePHP 1.3 and I'm currently in the process of adding a new language. I have the original .pot file and I generated a new .po file for the given language. So far so good, it's all working, however, now someone has to do the actual translation. I've send them the relevant .po file with explanations what to do but they seem to have problems dealing with plain text file. Is there a user friendly tool or piece of code that would actually allow them to translate the phrases one by one, without having to deal with text files?
You need a po editor. There are many out there for various platforms. Some free, some not. They usually provide a simple interface for viewing all the available translation strings and adding the translation next to them without need for viewing the po file in a text editor. My understanding is that many translators are familiar with this type of software so may already have one installed.
Check out this Stack Overflow question and answers for suggestions:-
What good alternatives to poEdit are there?
Setting up the multi language site I now need to decide which option I need to use for static text on the site. Let me explain my site setup and then if you can help me decide which solution to use.
The site is a CMS system that allows multiple domains to point to the same directory and serves content based on the domain name. So all domains share the same code. On the site I created blocks of code, called modules, that do specific jobs. So I might have a module that all it does is display the latest news from the database. I then can decide what page that module can display on and what site it will display on. So my question is, would gettext work for multiple domains that may have different modules showing up on different pages? Or should I just create a language file for each module that contains an array which has the language conversation for that specific module? So if I had 10 modules, each module would have its own language file and whatever page each module shows up it just refers to the array in the language file for that module to decide what text to show? Hope this makes sense, I read a lot about gettext and using the array version, but cant decide which one is better for this type of site setup.
A lot of CMS uses the array version. I have seen GetText as well for scalable applications. The array version is simpler especially when you want to manage the translation from a web interface.
It is a matter of preference of course.
In my opinion PHP gettext is the way to go. In all my projects I use the wordpress style for translation. http://codex.wordpress.org/Translating_WordPress and using the same functions naming convention:
__('message') // Return the translation
_e('message') // echo's the translation
_n('singular_message', 'plural_message', count ) // return singular or plural
I use poedit http://www.poedit.net/ to extract translatable strings from the PHP source and translate them to other languages. Storing and compiling the files in the required PHP gettext directory structure like this:
en_US/LC_MESSAGES/default.mo
nl_NL/LC_MESSAGES/default.mo
de_DE/LC_MESSAGES/default.mo
Note that .mo files are cached by PHP and changes in your .mo file are non existing until you restart the webserver. Pulling my hair out while developing I came across this very helpfull solution: http://blog.ghost3k.net/articles/php/11/gettext-caching-in-php
The whole gettext thing took me a while to work it out, but is was worth it. Once in place it saved me a great deal of time and allowed my clients to do the translation for their projects themselves.
If you want to activate a community for translating your project have a look at the web based translation tool Pootle.
In my experience, raw gettext isn't terribly well suited for a web site context where content changes over time and usually outside of a formal release cycle.
I'd recommend that you take a look at Zend_Translate (and Zend_Locale, if you want to localize dates, numbers, etc). Zend_Translate is a higher-level library that has adapters for various underlying methods (including gettext and arrays).
It's fairly well documented, and can be used as a standalone component.
In fact, I find gettext easier:
You can just echo / print _("your text"); and translate later
It is easy to be helped with getext editors
To generate the boostrap po file (iirc, the /source/ file), you can use etags that will make a kind of grep on your files. So you'll just have to translate tokens later.
So basically, everything works since the beginning of the project, it is then easier to start, and more convenient for upscale.
I would recommend using gettext. It's a well-established set of tools. There is a tool to automatically extract text strings from your source code (xgettext) and there are other tools that help you with translating your localization files, for example, poedit ( http://www.poedit.net/ ).
If you are running PHP 5.3 and/or have the intl extension installed, there's another option, too: messageformatter:
http://php.net/manual/en/class.messageformatter.php
This is very powerful, but it lacks -- in my opinion -- a little bit of documentation and might be overkill for your purpose. You can find some more information about this at the ICU project's page:
http://userguide.icu-project.org/formatparse/messages
I am planning to allow users to generate .POT files/.PO files through a PHP user interface as part of CMS solution. Once these files have been generated (the easy bit) I would like to allow my system to automatically convert these files into .MO files in response to a user (POST) request.
I have seen the following question on SO:
.po to .mo convertor in php?
I understand that I could run msgfmt by using PHP's exec() function, but that seems to be a Linux only solution, if I am correct? How would I do this on other operating systems? Some example code of how this may be done in practice would also be really useful, if anybody would be kind enough to demonstrate. This is quite different from the work I usually do!
This is only a concept at the moment but I hope I'm going along the right lines. If there are any additional thoughts/suggestions you have regarding this method, I'd be glad to hear them. Background information follows.
Additional Background Information - Not required:
I am retrieving the original English text by parsing simple template files that consist of nothing more than basic HTML and calls to <?php _('the gettext method'); ?>. These templates are parsed when edited/saved and the language entries are retrieved. The .POT file will then be generated. The user would now have to edit translations manually (through a simple interface, not directly) to update/prepare all the .PO files. Once this is done, I would need to be able to convert them to .MO files, as is the title of my question.
There are also PHP-only reimplementations of msgfmt if that is what you are looking for:
php-msgfmt
php.mo/gh
As alternative there would also be the Translate/Pootle webapp, with its php2po script, but there must also be some .mo conversion functions in it... (Ooops no, it's in Python.)
Both PHP's exec and the msgfmt GNU gettext utility are not a linux only solution. They work on multiple computer systems. As with PHP you can compile for multiple platforms (as it's done naturally), so the exec command is available on mutliple systems, the same applies to msgfmt. Start on the GNU gettext homepage to obtain a version for your system.
try https://github.com/oscarotero/Gettext.git
use Gettext\Translations;
chdir('....');
$translations = Translations::fromPoFile('messages.po');
$translations->toMoFile('messages.mo');
We're developing a multi-language website and in case of changes to the original text (English) they shouldn't appear on the site until all of the localized entries are changed accordingly. I don't think that's possible to do with gettext/POEdit alone (?). Another thing is concurrency of translation. If a bunch of people would edit the same gettext files on their PCs and then upload the changes to SVN, the situation when some translations were done by many people is inevitable.
Therefore it seems to be a good idea to store changed phrases in the database and once every language has its translation, make changes to po/mo files so that there is at every moment just actual information on the site.
Is it possible to make changes to gettext translation files with PHP? If not, should we forsake gettext in lieu of storing everything in the database?
Thanks
Well, I've tried a bunch of stuff and it seems that PEAR File/Gettext is the way to go. I seems to be kind of abandoned and files, created by POEdit and File/Gettext aren't binary similar, but I've checked the differences and they are mostly in metadata (which isn't needed for the proper functioning either way), except the hashtable, which isn't handled in the PHP package, but the docs for the mo state that the hashtable isn't required either and it's questionable whether is must be contained in those files :)
I have a few questions:
I know what gettext is. I've read a few posts where they mentioned xgettext and was curious as to what is the difference between the two.
How can I install xgettext on Windows?
And finally, does anybody have a tutorial on how to install the library php-gettext http://savannah.nongnu.org/projects/php-gettext/ (this one usually doesn't come with PHP) I've read about it in an article but I'm not sure how to get it working in Windows. The thing is, sometimes when you make changes, you need to restart Apache to see the new data with the gettext that comes with PHP (but with the library you don't need to restart it) so I wanted to use the library for development. Thanks!
In regards to the question:
I know what gettext is. I've read a few posts where they mentioned xgettext and was curious as to what is the difference between the two.
In short, gettext() is a function and xgettext is a utility program for extracting messages from source code.
In long, SO answer to Complete C++ i18n gettext() “hello world” example shows as part of the C++ source code file hellogt.cxx:
gettext("hello, world!")
The gettext() function is passed a text string that is used as an index to the message to be used at run-time. It returns the specified message for the language which is specified either in the code or at the time the program is invoked.
Then it shows:
xgettext --package-name hellogt --package-version 1.2 --default-domain hellogt --output hellogt.pot hellogt.cxx
which is a utility program used at build time to examine the source code file hellogt.cxx for text strings passed to gettext(). These are extracted and used to create the Portable Object Template file hellogt.pot.
The .pot file template is used by translators in the process of delivering the binary translated message file hellogt.mo used at run-time by gettext().
Install Cygwin and select the gettext-devel package.
This will install the xgettext.exe
The Zend Framework has a gettext Zend_Translate adapter that doesn't require the php gettext extention.
xgettext is part of gettext, it's a program that extracts translatable strings from program sources. See gettext's manual.
I don't know about its availability on Windows, Google tells me there's a port.
The online function reference reference tells me there is no xgettext.
Maybe they mean one of
ngettext dgettext dngettext dcgettext dcngettext
treating the 'x' like a wildcard