From 427c94dbbf3b6a3004107db8ebe3be8d42588791 Mon Sep 17 00:00:00 2001 From: Santhosh Thottingal Date: Sat, 27 Oct 2012 19:27:10 +0530 Subject: [PATCH] Avoid 404s in non-localized locales * Update jquery.i18n - if messageLocationResolver returns false for a locale, no server hit will be attempted * Refactor i18n preparation code to a new method * Use the ULS RL hooks to find out to which locales it is localized, pass that list to js to avoid hitting server. * Also avoid directory scanning in each request by putting the locale list in cache Fixes Bug 41454 Change-Id: I0c923b35db01b884e2dd55873dd5fb7384434645 --- UniversalLanguageSelector.hooks.php | 33 +++++++++++++++++++ lib/jquery.i18n.js | 13 ++++---- resources/js/ext.uls.init.js | 49 +++++++++++++++++++++-------- 3 files changed, 75 insertions(+), 20 deletions(-) diff --git a/UniversalLanguageSelector.hooks.php b/UniversalLanguageSelector.hooks.php index 01b853c6..75e52521 100644 --- a/UniversalLanguageSelector.hooks.php +++ b/UniversalLanguageSelector.hooks.php @@ -165,6 +165,39 @@ class UniversalLanguageSelectorHooks { global $wgULSGeoService; $vars['wgULSGeoService'] = $wgULSGeoService; + // ULS is localized using jquery.i18n library. Unless it knows + // the localized locales, it can create 404 response. To avoid that, + // send the locales available at server. Also avoid directory scanning + // in each request by putting the locale list in cache. + $cache = wfGetCache( CACHE_ANYTHING ); + $key = wfMemcKey( 'uls', 'i18n', 'locales' ); + $result = $cache->get( $key ); + + if ( $result ) { + $vars['wgULSi18nLocales'] = $result; + } else { + $mwULSL10nFiles = glob( __DIR__ . '/i18n/*.json' ); + + foreach ( $mwULSL10nFiles as $localeFile ) { + $mwULSL10nLocales[] = basename( $localeFile, '.json' ); + } + + $mwULSL10nFiles = glob( __DIR__ . '/lib/jquery.uls/i18n/*.json' ); + + foreach ( $mwULSL10nFiles as $localeFile ) { + $jqueryULSL10nLocales[] = basename( $localeFile, '.json' ); + } + + $vars['wgULSi18nLocales'] = array( + // Locales to which jQuery ULS is localized. + 'uls' => $jqueryULSL10nLocales, + // Locales to which Mediawiki ULS is localized. + 'ext-uls' => $mwULSL10nLocales, + ); + + // Cache it for 1 hour + $cache->set( $key, $vars['wgULSi18nLocales'], 3600 ); + } return true; } diff --git a/lib/jquery.i18n.js b/lib/jquery.i18n.js index fb0b60f5..7bdb5c47 100644 --- a/lib/jquery.i18n.js +++ b/lib/jquery.i18n.js @@ -49,7 +49,7 @@ // Override String.localeString method String.prototype.toLocaleString = function () { - var localeParts, localePartIndex, value, locale, fallbackIndex; + var localeParts, messages, localePartIndex, value, locale, fallbackIndex; value = this.valueOf(); locale = i18n.locale; @@ -65,12 +65,11 @@ var _locale = localeParts.slice( 0, localePartIndex ).join( "-" ); if ( !i18n.messageStore.messages[_locale] && i18n.options.messageLocationResolver ) { - // FIXME If messageloading gives 404, it keep on trying to - // load the file again and again - i18n.messageStore.load( - i18n.options.messageLocationResolver( _locale ), - _locale - ); + messages = i18n.options.messageLocationResolver( _locale, value ); + + if ( messages ) { + i18n.messageStore.load( messages, _locale ); + } } var message = i18n.messageStore.get( _locale, value ); diff --git a/resources/js/ext.uls.init.js b/resources/js/ext.uls.init.js index 3388a884..5355dba3 100644 --- a/resources/js/ext.uls.init.js +++ b/resources/js/ext.uls.init.js @@ -90,26 +90,49 @@ return unique; }; - $( document ).ready( function () { - var extensionPath, i18n, $ulsTrigger, previousLanguages, previousLang; + /** + * i18n initialization + */ + function i18nInit () { + var extensionPath, locales, i18n; extensionPath = mw.config.get( 'wgExtensionAssetsPath' ) - + '/UniversalLanguageSelector/'; - // i18n initialization + + '/UniversalLanguageSelector/'; + + locales = mw.config.get( 'wgULSi18nLocales' ); i18n = $.i18n( { locale: currentLang, - messageLocationResolver: function ( locale ) { - return extensionPath + 'i18n/' + locale + '.json'; + messageLocationResolver: function ( locale, messageKey ) { + // Namespaces are not available in jquery.i18n yet. Developers prefix + // the message key with a unique namespace like ext-uls-* + + if ( messageKey.indexOf( 'uls' ) === 0 ) { + if ( $.inArray( locale, locales['uls'] ) >= 0 ) { + return extensionPath + 'lib/jquery.uls/i18n/' + locale + '.json'; + } + + return false; + } + + if ( messageKey.indexOf( 'ext-uls' ) === 0 ) { + if ( $.inArray( locale, locales['ext-uls'] ) >= 0 ) { + return extensionPath + 'i18n/' + locale + '.json'; + } + + return false; + } } } ); - // localization for jquery.uls - i18n.load( extensionPath + 'lib/jquery.uls/i18n/' + currentLang + '.json', currentLang ); - // localization for jquery.uls- fallback locale - i18n.load( extensionPath + 'lib/jquery.uls/i18n/en.json', 'en' ); - // localization for mediaWiki ULS - i18n.load( extensionPath + 'i18n/' + currentLang + '.json', currentLang ); - // localization for mediaWiki ULS- fallback locale + + // localization for mediaWiki ULS - fallback locale i18n.load( extensionPath + 'i18n/en.json', 'en' ); + } + + $( document ).ready( function () { + var $ulsTrigger, previousLanguages, previousLang; + + // JavaScript side i18n initialization + i18nInit(); $ulsTrigger = $( '.uls-trigger' ); previousLanguages = mw.uls.getPreviousLanguages() || [];