CJuiDatePicker extended for more/better language support

You are viewing revision #1 of this wiki article.
This version may not be up to date with the latest version.
You may want to view the differences to the latest version.

next (#2) »

The number of languages supported by the stander CJuiDatePicker implementation is limited and the language code to use is different from the application's language code. This Wiki shows how to improve on that.

Basically, the derived implementation of the CJuiDatePicker class below does two things:

  1. Convert the language code to the one required by the CJuiDatePicker;
  2. Reference other locality files that I got from another open source project (Kooboo).

It will also get the language from the application if the widget language option is empty.

First, add the following to your setup. I call the file 'YJuiDatePicker.php'. You also have to create a directory 'assets/lang'. This directory will hold the 'jquery.ui.datepicker*.js files'.

The '$coreLanguages' property lists all the languages provided for the original Widget in the Framework. If any language gets added to the framework, just update it there.

<?php
Yii::import('zii.widgets.jui.CJuiDatePicker');
/**
 * Extends CJuiDatePicker with more language support.
 */
class YJuiDatePicker extends CJuiDatePicker {
    /**
     * Languages supported by the Yii CJuiDatePicker.
     */
    public $coreLanguages=array('en','bg', 'bs', 'ca', 'cs', 'cy-GB', 'da', 'de', 'el', 'en-AU', 'en-GB', 'en-NZ', 'eo', 'es', 'et', 'eu', 'fa', 'fi', 'fo', 'fr-CH', 'fr', 'gl', 'he', 'hi', 'hr', 'hu', 'hy', 'id', 'is', 'it', 'ja', 'ka', 'kk', 'km', 'ko', 'lb', 'lt', 'lv', 'mk', 'ml', 'ms', 'nl-BE', 'nl', 'no', 'pl', 'pt-BR', 'pt', 'rm', 'ro', 'ru', 'sk', 'sl', 'sq', 'sr-SR', 'sr', 'sv', 'ta', 'th', 'tj', 'tr', 'uk', 'vi', 'zh-CN', 'zh-HK', 'zh-TW');

    /**
     * (non-PHPdoc)
     * @see CJuiWidget::init()
     */
    public function init() {
        if($this->language==='') {
            $lang=Yii::app()->language;
            // Get language from environment - used only two characters.
            $this->language=substr(Yii::app()->language,0,2);
            $loc=strtoupper(substr($lang,3,2));
            if($loc!=='') {
                $this->language.='-'.$loc;
            }
        }
        parent::init();
    }

    /**
     * (non-PHPdoc)
     * @see CJuiDatePicker::run()
     */
    public function run() {
        $this->registerScripts();
        parent::run();
    }

    /**
     * Registers common widget assets and scripts.
     *
     * Private utility method to publish and register widget related files
     * and scripts.
     */
    private function registerScripts() {
        $assetFolder = __DIR__.DIRECTORY_SEPARATOR.'assets';
        $assetUrl = Yii::app()->getAssetManager()->publish($assetFolder,false,-1,YII_DEBUG);

        /* @var $cs CClientScript */
        $cs=Yii::app()->clientScript;
        if(!in_array($this->language,$this->coreLanguages)) {
            $cs->registerScriptFile($assetUrl.'/lang/jquery.ui.datepicker-'.$this->language.'.js');
        }
    }
}

Second get the 'jquery.ui.datepicker-*.js' files. I got them from the Kooboo project. If you get them from another source, you may need to change the code a tiny bit to accomodate the file naming. The Kooboo regional datepicker files are not perfect - for instance the 'french' file still has English texts in it, while the french file provided by Yii is ok.

Third, you need to update all the '.js' language files to avoid getting Chinese tokens in your datepickers. You have to add entries for yearSuffix and weekHeader:

jQuery(function($){
	$.datepicker.regional['fr'] = {"Name":"fr","closeText":"Close","prevText":"Prev","nextText":"Next","currentText":"Today","monthNames":["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre",""],"monthNamesShort":["janv.","févr.","mars","avr.","mai","juin","juil.","août","sept.","oct.","nov.","déc.",""],"dayNames":["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],"dayNamesShort":["dim.","lun.","mar.","mer.","jeu.","ven.","sam."],"dayNamesMin":["di","lu","ma","me","je","ve","sa"],"dateFormat":"dd/mm/yy","firstDay":1,"isRTL":false,

yearSuffix:"",weekHeader:""

};
	$.datepicker.setDefaults($.datepicker.regional['fr']);
});

For that I use a replacement using perl:

perl -i -p -e 's/};/,yearSuffix:"",weekHeader:"";/' *.js

Indeed, observation of the Kooboo files shows that there is only one sequence of '};' in the files and we can add 'yearSuffix' and 'weekHeader' there. So it suffices to use '};' as an anchor to make the replacement.

Finally, just use the YJuiDatePicker the same way as you would use the CJuiDatePicker, you only have to reference the YJuiDatePicker instead of the CJuiDatePicker. Further you probably no longer have to set the language explicitally as the new Widget gets it from the application.