Celavi | blog

How to add plural support to Gettext Adapter in Zend Framework

by Celavi on Jul.06, 2009, under PHP, Zend Framework

Zend_Translate_Gettext Plural SupportThis tutorial is deprecated. With Zend Framework 1.9 plural support to Gettext adapter has been implemented.

One of the most popular discussions on forums, mailing lists and blogs regarding Zend Framework and its component Zend_Translate are about plural support in the gettext adapter. The Gettext Adapter is the Adapter which is used most frequently. Gettext is a translation source format which was introduced by GNU, and is now used worldwide. It is not human readable, but there are several freeware tools (for instance, POEdit), which can be very helpful. Zend_Translate does not use PHP’s gettext extension because it is not multi-thread aware. Adapter reads the mo files directly, therefore it does not need PHP’s workaround. Because Zend has focused on a simple API which covers many sources (array, scv, gettext, ini, tbx, tmx, qt, xliff, xmltm) , implementation of plurals (which are native to translation in general, not unique to gettext) would be a hard task in early deployment of Zend Framework.

First step

in implementing plural support to Gettext Adapter in Zend Framework is understanding how gettext handles plural forms. I won’t get into details here, you can read more about this at GNU / gettext . For us the crucial information is about the plural form selections, which has to be stored in the header of entry of the PO file (the one with the empty msgid string). The plural form information looks like this:
 Bash |  copy code |? 
1
Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);
Here you can find the list of plural forms, as used by Gettext PO, that are appropriate to each language.

Second step

in achieving our goal would be extracting that information from PO file and storing it somewhere safe for later use. I've decided to store it as a translation keyword "Plural-Forms" and then use it as necessary. The supplemented code which is added to Zend_Translate_Adapter_Gettext is:
 PHP |  copy code |? 
01
//store PluralForm
02
if ($this->_adapterInfo[$filename] != 'No adapter information available') {
03
    $this->_data[$locale]['Plural-Forms'] = $this->_getPluralForms($this->_adapterInfo[$filename]);
04
}
05
 
06
/**
07
* Retrieve Plural-Forms string from MO file
08
*
09
* @param array $meta
10
* @return string
11
*/
12
protected function _getPluralForms($meta)
13
{
14
    $pluralForms = 'nplurals=2; plural=(n != 1);';
15
    $array = array();
16
    foreach (explode("\n", $meta) as $info) {
17
        if ($info = trim($info)) {
18
            list($key, $value) = explode(':', $info, 2);
19
        $array[trim($key)] = trim($value);
20
        }
21
    }
22
    if (array_key_exists('Plural-Forms', $array)) {
23
        $pluralForms = $array['Plural-Forms'];
24
    }
25
 
26
    return $pluralForms;
27
}

Third and final step

is to write a function which would return translated plural form for the provided text, plural version of text, count and optional parameters.
This is just a piece of code from the whole translate class which holds Zend_Translate object (Zend_Translate_Adapter_Gettext):
 PHP |  copy code |? 
01
/**
02
* Translate Plural message
03
*
04
* @param string $text simple text
05
* @param string $plural plural version of text
06
* @param int $count count
07
* @param string/array $params
08
* @return string
09
*/
10
public static function translatePlural($text, $plural, $count, $params = array())
11
{
12
    //set Plural Forms String
13
    self::_setPluralForms();
14
 
15
    if(!is_string($text) || strlen($text) == 0)
16
        return '';
17
 
18
    // find out the appropriate form
19
    $select = self::_selectString($count);
20
 
21
    // this should contains all strings separated by NULLs
22
    $key = $text.chr(0).$plural;
23
    // verify if translation Exists
24
    self::_verifyMessage($key);
25
 
26
    if (!self::getInstance()->_translate->isTranslated($key)) {
27
        $translated = ($count != 1) ? $plural : $text;
28
    } else {
29
        $result = self::getInstance()->_translate->translate($key);
30
        $list = explode(chr(0), $result);
31
        $translated =  $list[$select];
32
    }
33
    // return formated translation
34
    return vsprintf($translated, $params);
35
}

Use case

within action controller

 PHP |  copy code |? 
1
//Change Locale to Slovene
2
ZendX_T::setLocale('sl_SI');
3
$threeSeconds = ZendX_T::translatePlural("%d second","%d seconds", 3, 3);
4
/**
5
$threeSeconds will have value '3 sekunde'
6
*/

The Zend Framework way of implementing this thing right would be writing a View_Helper. :) I'll leave that task to you.

Source Code

Download a zip archive of the project

  zf_gettext_plural.zip (4.3 MiB, 126 hits)

or grab your copy at GitHub. Feel free to download and judge for yourself. :D



And remember, contributions earn you karma. ;)
Bookmark and Share
1 Comment :, , , more...

How to make old extensions work in Firefox 3.5

by Celavi on Jul.03, 2009, under Internet

Mozilla Firefox 3.5 was released a few days ago. This is great news for us web developers, but not all add-ons have been updated to be compatible with the new version yet, YSlow being one of them. You can force an incompatible extension to work with Firefox 3.5 by disabling the compatibly check that Firefox performs before each install.

Instructions


  • Type “about:config” (without quotation marks) into the address bar and click the Agree button
  • Right-click anywhere in the window and choose New – Boolean. Name the new config value “extensions.checkCompatibility” (without quotation marks) and set it to false
  • Restart Firefox


NOTE: This might lead to unexpected behavior or even a crash. Make sure that you properly backup your add-ons before editing.



before messing with FF 3.5 config
before editing Firefox 3.5 config
New config entry
new config entry
YSlow is working again
YSlow working




And remember, contributions earn you karma. ;)
Bookmark and Share
Leave a Comment :, , , more...

Easiest way to install VMware Tools on Ubuntu 9.04 under VMware Fusion 2.04

by Celavi on Jul.02, 2009, under Mac OS X, Ubuntu / Linux

Vmware Tools installPrimarily I’m using VMware Fusion for testing web applications on different operating systems and browsers. I’ve recently downloaded Ubuntu 9.04 and gave it a try. Working on guest operating system without VMware Tools installed is a real pain in the ass. The rigid constant locking/unlocking of the mouse within the window, low-res graphics… So the obvious step was clicking on the “Install VM Ware Tools” button in the menu bar.  After unpacking the archive, installation and a restart, everything seemed to be working fine, except the mouse. I still had to lock/unlock it manually within the window! *ranting*

For safety’s sake I did took a snapshot before installing these tools and have managed to restore the system to its previous state. With some help of good ol’ uncle Google I have found the answer. My version of VMware Fusion (2.04) was released prior to the release of Ubuntu 9.04, so there are some issues with the installation. I stumbled upon Chrysaor.info. They’re providing VMware images for Debian, OpenBSD and Ubuntu. Check the FAQ section for: “How can I install VMware Tools in Ubuntu 9.04?



Instructions are pretty straightforward. You need to open a terminal window, execute few commands, hit Enter as defaults are OK, reboot and you are done. :D

 Bash |  copy code |? 
1
wget http://chrysaor.info/scripts/ubuntu904vmtools.sh
2
sudo bash ./ubuntu904vmtools.sh


And remember, contributions earn you karma. ;)
Bookmark and Share
1 Comment :, , , , , , , more...

The necessary “first” post

by Celavi on Jun.28, 2009, under Personal

Hello World! :P



Well, today is the day. I’ve finally managed to set up a blog in English. Some of you may have read my blog in Slovene (Internet Solutions) – and I must note that this blog will contain similar, if not the same, content. I registered this domain in January 2008, and since then this has been just a dumping ground. I’ve made my final decision about this step after I returned from Netherlands, where I was attending the Dutch PHP Conference 2009 (DPC).

Considering the fact that PHP is distributed under Open Source license, there was much debating why developers should contribute code to an Open Source Software projects. Especially one discussion was completely devoted to contribution. Software Architect for Zend Framework Matthew Weier O’Phinney was talking about various ways we can contribute to open source projects and earn our “karma”. Developers who are using the work of others, should take the responsibility and contribute back, even if this just means to translate a few pages of Project Documentation.



Hopefully I will be expecting some useful articles / contributions here in the nearby future.



And remember, contributions earn you karma ;)
Bookmark and Share
Leave a Comment :, , more...

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Archives