Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for PHP's gettext() #61

Open
lurkie opened this issue Oct 22, 2020 · 8 comments
Open

Support for PHP's gettext() #61

lurkie opened this issue Oct 22, 2020 · 8 comments

Comments

@lurkie
Copy link
Contributor

lurkie commented Oct 22, 2020

I was drawn to this plugin to assist me in our project where we use PHP gettext() and its related *gettext() functions for translations using .po and .mo files. It seems that this plugin does not support gettext. Am I correct? If so, please consider this a feature request. If not, how should I configure this plugin for PHP gettext?

@nyavro
Copy link
Owner

nyavro commented Oct 22, 2020

Hi!
I would implement this feature, if you give me some more details about how this should work.
Could you please give some examples of .po and .mo files? What's the folder structure? How do translation keys look like?
I'm not familiar with PHP, so I need help here.

Evgeniy

@lurkie
Copy link
Contributor Author

lurkie commented Oct 22, 2020

Hi Evgeniy,

Fortunately, PHP is something I am familiar with 🙂. I created a small demo, you can see it at my fork (fork will probably be deleted some time in the future). This commit shows a demo of gettext, and includes a few sample .mo and .po files.

The folder structure is as following. The LC_MESSAGES directory is a requirement of gettext. Here I used 'messages' as the domain.

some_resource_dir/
   |- de_DE
   |     \- LC_MESSAGES
   |         |- messages.mo
   |         \- messages.po
   |- en_US
   |     \- LC_MESSAGES
   |         |- messages.mo
   |         \- messages.po
   ...

A .po file (portable object) is a plain text file containing pairs of msgid as the key, and msgstr as the translation for singular texts. Plural texts have a msgid_plural-tag combined with multiple msgstr[n]. The msgid can be any text string in my experience. We're using the complete string as a source, but this is not a best practice (as described in this article). Using key strings which resembles the meaning is better.
The .po file needs to be compiled into a binary .mo file (machine object). This can be done using the tool msgfmt. You might need to compile my example files it again as the .mo files are not intended to be portable. More info about gettext can be found at GNU's documentation.

Please note that the gettext() function has an alias: _(). In our usecase, we have __() and ___() as well, which are wrapper functions for gettext + sprintf and ngettext + sprintf combined. Using alias functions is a practice I encountered before, e.g. Magento has a __() function (although Magento does not use gettext). For this, a configurable list of functions to analyze for i18n would be great.

I hope this helps you understand how gettext works. Please let me know if you need more information.

Lurkie

@nyavro
Copy link
Owner

nyavro commented Oct 22, 2020

Awesome!
I've grabbed your commit as pull request to nyavro:master: #64, if you don't mind.
Thanks for demo, now I got the problem. Let's see what could be done here.

@nyavro
Copy link
Owner

nyavro commented Oct 22, 2020

Do I get it right that for plural translations used another function, ngettext. So, ngettext also may have several aliases?
And one more question: is there 1-2-5 notation for plurals? I see in examples only 1 and 2.
I mean in i18next you only need to specify plurals for 1,2 and 5 items, so it picks correct translation for any number. Is it the same principle here?

nyavro added a commit that referenced this issue Oct 22, 2020
@nyavro
Copy link
Owner

nyavro commented Oct 23, 2020

One more question. Here is how path to messages configured: 'translations/$lang/LC_MESSAGES/messages.po'. So the translation file itself is under LC_MESSAGES folder, and lang folder is LC_MESSAGES parent. Is it possible to configure the path this way:
'translations/LC_MESSAGES/$lang/messages.po' or '$lang/translations/LC_MESSAGES/messages.po'? If yes, then we need one more configuration setting.

@nyavro
Copy link
Owner

nyavro commented Oct 23, 2020

nyavro added a commit that referenced this issue Oct 23, 2020
@lurkie
Copy link
Contributor Author

lurkie commented Oct 23, 2020

I'm not too familiar with all the nitty-gritty details of plurals, but gettext does support plurals quite well. For example, Arabic has 6 plural forms (according to the docs), and can be configured in the .po file using 'Plural-Forms'. As long as you can specify the plural form using this kind of expressions, you should be good to go. The docs have examples for a lot of languages.

Plural-Forms: nplurals=6; \
    plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 \
    : n%100>=11 ? 4 : 5;

The *ngettext() functions have two text parameters, which should both exists in the .po (and .mo) file in the msgid and msgid_plural tags respectively. Please note that gettext as implemented in PHP has several functions to override the domain or category for a single call, the PHP manual has more info on it.

On the path layout: the structure is pretty rigid. You can select a base directory, the remaining part is fixed. Meaning: you need to work with this format: $base_dir/$language/LC_MESSAGES/$domain.po. I am not aware of any other order of path segments.

I actually have the GNU GetText files support -plugin installed, but unfortunately it only provides syntax highlighting for .po files. Which is still pretty nice to have though. The change with my example has been pushed to my fork, as I wasn't sure you want it in your repo. I have no problem if you include it.

nyavro added a commit that referenced this issue Oct 23, 2020
Implementation of Reference contributor
nyavro added a commit that referenced this issue Oct 23, 2020
nyavro added a commit that referenced this issue Oct 24, 2020
nyavro added a commit that referenced this issue Oct 25, 2020
nyavro added a commit that referenced this issue Oct 29, 2020
nyavro added a commit that referenced this issue Oct 29, 2020
nyavro added a commit that referenced this issue Oct 29, 2020
@Christophe31
Copy link

You made and merged a branch, awesome. Just to let you know, django(python) use same gettext/po tools.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants