I open this issue to follow the evolution of this patch for D7 that allows the translation system to get translations from a pre-compiled binarry gettext file.

Summary:

The patch makes Drupal use the php gettext extension to retrieve the string translations from a binary gettext file (.mo).

The pre-compile gettext file is created with "msgfmt -o messages.mo drupal-es.po".

When you place it at sites/whatever/locale/es/LC_MESSAGES/messages.mo, Drupal detects it and uses the gettext function to retrieve the translations from the file.

It improves performance even in a clean Drupal install.

Of course you loose the flexibility of the string translating interface but for sites with little changes to the translations and where performance is key this helps with hardware resources and scalability.

Reference post: http://al.quimia.net/en/blog/improving-drupal-performance-using-native-g...

CommentFileSizeAuthor
7.x-gettext.patch1.96 KBPedro Lozano
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

plach’s picture

Component: language system » locale.module

String translation issues concern the Locale queue: changing component accordingly.

Gábor Hojtsy’s picture

Status: Active » Needs work

Drupal and Gettext related comments:

1. To make Drupal use alternate methods of lookup, Drupal usually does variable_get('locale_use_gettext', FALSE) like settings. Then settings.php can modify $conf['locale_use_gettext'] or there can be a UI to set these. With your global variable approach that does not work.

2. Drupal allows for arbitrary language translations. For example, contact module can send 3 emails in one HTTP request in 2 different languages. Therefore initializing the system for language and then considering it done does not work. The language requested needs to be obeyed.

3. Drupal supports the gettext standard context specification. PHP does not seem to support that. Very unfortunate I must say for this patch. Because Drupal will just request t('View') and whether that is a verb to view something or a noun to refer to a views view or a noun to refer to some other type of view is provided by the context. Same applies to "May". It can be a short month name, a long month name or other things. Gettext certainly support this and we want to expand on this in Drupal 8 even more, so looks like PHP has a serious limitation here. At worst you could mimic this by having different text domains per context and then switch between them as needed, but that sounds pretty hackish.

4. Drupal uses t() indirectly form format_plural() as well to look up strings. For your solution to work, you'd need to abandon actually using the plural syntax in gettext for those strings, and use Drupal's workaround to support string level lookups. I assume this might be in your converter script, is it?

Damien Tournoud’s picture

Status: Needs work » Closed (won't fix)
+    putenv('LANG='. $lang_code);
+    setlocale(LC_ALL, $lang_code);

The Gettext extension has been in PHP for ages. There is a reason we are not using it: it is utterly broken. The Gettext extension:

  • relies on an environment variable which is set *per process* (and thus completely broken in any multi-threaded SAPI),
  • and relies on the system locales: a language that is not configured on the server will not be loaded by Gettext

As a consequence, this ties Drupal to the server environment which is completely unacceptable. A few years back I wrote some code to read strings from .mo files directly, but it turned out less efficient then querying the database (especially since we cache small strings).

A lot of things can be done to improve the performance of locale() (especially coming up with a better caching strategy), but using the Gettext extension is not one of them.

Dave Reid’s picture

setlocale(LC_ALL, $lang_code); is one of the most horrible, horrible things you could ever do. This is the source of many, many problems like converting database default float values of '0.8' to '0,8' which then creates invalid SQL.

trunks’s picture

Status: Closed (won't fix) » Needs work

Dave: it's possible to fix it using LC_MESSAGES instead of LC_ALL for setlocale()

Damian: I think your second point isn't right. It's not an issue but a requisite. I mean, if you want to use cleanpaths on your Drupal, yo need to install mod_rewrite, so if you want to use improved internationalization for your Drupal (more performance) you need to install those languges for gettext on your server (it's not critical since you can use the current locale system -and not select the other one-).

About the first point from your comment, I think we can discuss some workarounds to get clues and solve the problem. Don't you?

Damien Tournoud’s picture

Status: Needs work » Closed (won't fix)

Both of my points are very valid. If you are ready to prove me wrong, do it. But for me this is definitely a won't fix.

Gábor Hojtsy’s picture

We can try and make t() or locale() replaceable in some way like the cache system or the mail system if there is enough interest and we can make it work without much performance problems on out of the box sites however, no?

Damien Tournoud’s picture

Getting the translation subsystem properly pluggeable is in the scope of all the other issues (#361597: CRUD API for locale source and locale target strings and friends).

Gábor Hojtsy’s picture

Well, I don't think regular API changes will make that possible since we are very wary of putting more logic in t() due to the performance impact it has. It would be very easy to fix this by putting in a general lookup hook that contribs can hook into and provide the string before we look in the db, but that would (probably unnecessarily) degrade performance for out of the box sites, so...

Now that I'm thinking of it, if someone can serialize an ArrayObject (http://php.net/manual/en/class.arrayobject.php) into a locale_custom_strings_$langcode variable, then they can do this pretty much in Drupal 7 contrib, because the array lookup is always attempted. Sounds like a possible but very hackish solution, isn't it :)

pounard’s picture

Sub. (A PHP : Gettext implementation would be really great).

Gábor Hojtsy’s picture

@pounard: from what it looks like #1213510: A modern t() would be able to enable it for a contributed module to do it.

andypost’s picture