Gettext Support for windows & linux

Hello here my solution to implement the real gettext into Yii framework.

I know Yii support gettext him self , but string parsing to open a compiled is 10 000 time slower than the real gettext.

My goal was to get a easy implementation and very low cpu / memory usage.

Gettext-NOTE: inside a gettext .po file you should only use LineFeed(\n) never use CarriageReturnLineFeed(\r\n) to create a new line. thoses are gettext standart. i am saying since i know some of you are editing .po file with normal text editor under windows and that will not make a good .po/.mo file.

Gettext-NOTE2: any change to a gettext file will not show up until you RESTART your http-deamon(apache httpd)

Usage :

     echo Yii::t("myCategory", "This is just a test");

Implementation :

  • edit your config file to reflect that






MyCGettextMessageSource :

  • create a file where ever you want name it MyCGettextMessageSource.php and add that class to that file.





 *  To make this work you need directory structure like that:

 *      .../protected/messages/gettext/LC_MESSAGES/

 *      File name structure goes like this: 


 *          lang        : lang code returned by Yii

 *          category    : category you specified for your message in Yii::t('category',$message)

 *          mo          : the normal extensions for a valid gettext compiled file



 *  To make this work add this line to the file /etc/locale.gen , create the file if not exists

 *      gettext UTF-8



class MyCGettextMessageSource extends CMessageSource



	 * @var string the base path for all translated messages. Defaults to null, meaning

	 * the "messages" subdirectory of the application directory (e.g. "protected/messages").


	public $basePath;


         * @var string used to fool putenv on windows system, this is a FAKE locale value

         * default will be "gettext" mean /LC_MESSAGES will be searched there


        private $fakeLocale = 'gettext';




         * @var type array , keep tract of the last domain name used and charset

         * to make less call to gettext functions


        private $lastDomain;


	 * Initializes the application component.

	 * This method overrides the parent implementation by preprocessing

	 * the user request data.


	public function init()






            $this->lastDomain = array('name'=>'','charset'=>'');

            if( strncasecmp(PHP_OS,'WIN',3)===0 )

                putenv("LANG=$this->fakeLocale");       //windows


                setlocale(LC_MESSAGES,$this->fakeLocale);    //linux

            // handle for missing file 

            $this->attachEventHandler('onMissingTranslation', array('MyCGettextMessageSource','handleMissingFile'));



	 * Translates the specified message.

	 * If the message is not found, an {@link onMissingTranslation}

	 * event will be raised.

	 * @param string $category the category that the message belongs to

	 * @param string $message the message to be translated

	 * @param string $language the target language

	 * @return string the translated message


	protected function translateMessage($category,$message,$language)


            if($this->lastDomain['name'] !== "$language.$category" || $this->lastDomain['charset'] !== Yii::app()->charset)


                $this->lastDomain['name'] = "$language.$category";

                bindtextdomain($this->lastDomain['name'], $this->basePath);


                bind_textdomain_codeset($this->lastDomain['name'], Yii::app()->charset);



            if(!file_exists("{$this->basePath}/{$this->fakeLocale}/LC_MESSAGES/$language.$") && $this->hasEventHandler('onMissingTranslation'))


                $event=new CMissingTranslationEvent($this,$category,$message,$language);


                return $message;


            return _($message);


        // since we are using real gettext we do not need that

        protected function loadMessages($category,$language){}


        // handle onMissingTranslation

        public static function handleMissingFile($event)


            Yii::log("Missing file for translation {$event->language}.{$event->category}", 'warning','application.extensions.MyCGettextMessageSource');



P.S. love is everywhere