mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
ENHANCEMENT Added javascript i18n support through Requirements::process_i18n_javascript() and ss.i18n javascript lib
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@63566 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
ef7f988b3b
commit
7c0b69ea34
@ -285,6 +285,9 @@ class Requirements {
|
|||||||
// Combine files - updates Requirements::$javascript and Requirements::$css
|
// Combine files - updates Requirements::$javascript and Requirements::$css
|
||||||
self::process_combined_files();
|
self::process_combined_files();
|
||||||
|
|
||||||
|
//
|
||||||
|
self::process_i18n_javascript();
|
||||||
|
|
||||||
foreach(array_diff_key(self::$javascript,self::$blocked) as $file => $dummy) {
|
foreach(array_diff_key(self::$javascript,self::$blocked) as $file => $dummy) {
|
||||||
$path = self::path_for_file($file);
|
$path = self::path_for_file($file);
|
||||||
if($path) {
|
if($path) {
|
||||||
@ -346,6 +349,35 @@ class Requirements {
|
|||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Automatically includes the necessary lang-files from the module
|
||||||
|
* according to the locale set in {@link i18n::$current_locale}.
|
||||||
|
* Assumes that a subfolder /javascript exists relative to the included
|
||||||
|
* javascript file, with a file named after the locale -
|
||||||
|
* so usually <mymodule>/javascript/lang/en_US.js.
|
||||||
|
*
|
||||||
|
* Caution: Assumes the manual inclusion of sapphire/javascript/i18n.js
|
||||||
|
* before
|
||||||
|
*/
|
||||||
|
protected static function process_i18n_javascript() {
|
||||||
|
foreach(array_diff_key(self::$javascript,self::$blocked) as $file => $dummy) {
|
||||||
|
if(preg_match('/^http[s]?/', $file)) continue;
|
||||||
|
|
||||||
|
$absolutePath = Director::baseFolder() . '/' . $file;
|
||||||
|
$absoluteLangPath = dirname($absolutePath) . '/lang/' . i18n::get_locale() . '.js';
|
||||||
|
$absoluteDefaultLangPath = dirname($absolutePath) . '/lang/' . i18n::default_locale() . '.js';
|
||||||
|
foreach(array($absoluteDefaultLangPath, $absoluteLangPath) as $path) {
|
||||||
|
if(Director::fileExists($path)) {
|
||||||
|
$langFile = Director::makeRelative($path);
|
||||||
|
// Remove rogue leading slashes from Director::makeRelative()
|
||||||
|
$langFile = preg_replace('/^\//', '', $langFile);
|
||||||
|
self::$javascript[$langFile] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
@ -1,12 +1,183 @@
|
|||||||
/**
|
if(typeof(ss) == 'undefined') ss = {};
|
||||||
* Misc helpers
|
|
||||||
|
/*
|
||||||
|
* Lightweight clientside i18n implementation.
|
||||||
|
* Caution: Only available after DOM loaded because we need to detect the language
|
||||||
|
*
|
||||||
|
* Based on jQuery i18n plugin: 1.0.0 Feb-10-2008
|
||||||
|
* @requires jQuery v1.1 or later
|
||||||
|
*
|
||||||
|
* Examples at: http://recurser.com/articles/2008/02/21/jquery-i18n-translation-plugin/
|
||||||
|
* Dual licensed under the MIT and GPL licenses:
|
||||||
|
* http://www.opensource.org/licenses/mit-license.php
|
||||||
|
* http://www.gnu.org/licenses/gpl.html
|
||||||
|
*
|
||||||
|
* Based on 'javascript i18n that almost doesn't suck' by markos
|
||||||
|
* http://markos.gaivo.net/blog/?p=100
|
||||||
*/
|
*/
|
||||||
var i18n = Class.create();
|
ss.i18n = Class.create();
|
||||||
i18n = {
|
ss.i18n = {
|
||||||
|
|
||||||
|
currentLocale: null,
|
||||||
|
|
||||||
|
defaultLocale: 'en_US',
|
||||||
|
|
||||||
|
lang: {},
|
||||||
|
|
||||||
|
init: function() {
|
||||||
|
this.currentLocale = this.detectLocale();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set_locale()
|
||||||
|
* Set locale in long format, e.g. "de_AT" for Austrian German.
|
||||||
|
* @param string locale
|
||||||
|
*/
|
||||||
|
setLocale: function(locale) {
|
||||||
|
this.currentLocale = locale;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getLocale()
|
||||||
|
* Get locale in long format. Falls back to i18n.defaut_locale.
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
getLocale: function() {
|
||||||
|
return (this.currentLocale) ? this.currentLocale : this.defaultLocale;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* _()
|
||||||
|
* The actual translation function. Looks the given string up in the
|
||||||
|
* dictionary and returns the translation if one exists. If a translation
|
||||||
|
* is not found, returns the original word
|
||||||
|
*
|
||||||
|
* @param string entity
|
||||||
|
* @param string fallbackString
|
||||||
|
* @param int priority (not used)
|
||||||
|
* @param string context Give translators context for the string
|
||||||
|
* @return string : Translated word
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
_t: function (entity, fallbackString, priority, context) {
|
||||||
|
if (this.lang && this.lang[this.getLocale()] && this.lang[this.getLocale()][entity]) {
|
||||||
|
return this.lang[this.getLocale()][entity];
|
||||||
|
} else if (this.lang && this.lang[this.defaultLocale] && this.lang[this.defaultLocale][entity]) {
|
||||||
|
return this.lang[this.defaultLocale][entity];
|
||||||
|
} else if(fallbackString) {
|
||||||
|
return fallbackString;
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
addDictionary: function(locale, dict) {
|
||||||
|
if(typeof(this.lang[locale])) {
|
||||||
|
this.lang[locale] = dict;
|
||||||
|
} else {
|
||||||
|
this.lang[locale] += dict;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stripStr()
|
||||||
|
*
|
||||||
|
* @param string str : The string to strip
|
||||||
|
* @return string result : Stripped string
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
stripStr: function(str) {
|
||||||
|
return str.replace(/^\s*/, "").replace(/\s*$/, "");
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stripStrML()
|
||||||
|
*
|
||||||
|
* @param string str : The multi-line string to strip
|
||||||
|
* @return string result : Stripped string
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
stripStrML: function(str) {
|
||||||
|
// Split because m flag doesn't exist before JS1.5 and we need to
|
||||||
|
// strip newlines anyway
|
||||||
|
var parts = str.split('\n');
|
||||||
|
for (var i=0; i<parts.length; i++)
|
||||||
|
parts[i] = stripStr(parts[i]);
|
||||||
|
|
||||||
|
// Don't join with empty strings, because it "concats" words
|
||||||
|
// And strip again
|
||||||
|
return stripStr(parts.join(" "));
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* printf()
|
||||||
|
* C-printf like function, which substitutes %s with parameters
|
||||||
|
* given in list. %%s is used to escape %s.
|
||||||
|
*
|
||||||
|
* Doesn't work in IE5.0 (splice)
|
||||||
|
*
|
||||||
|
* @param string S : string to perform printf on.
|
||||||
|
* @param string L : Array of arguments for printf()
|
||||||
|
*/
|
||||||
|
printf: function(S) {
|
||||||
|
if (arguments.length == 1) return S;
|
||||||
|
|
||||||
|
var nS = "";
|
||||||
|
var tS = S.split("%s");
|
||||||
|
|
||||||
|
var args = [];
|
||||||
|
for (var i=1, len = arguments.length; i <len; ++i) {
|
||||||
|
args.push(arguments[i]);
|
||||||
|
};
|
||||||
|
|
||||||
|
for(var i=0; i<args.length; i++) {
|
||||||
|
if (tS[i].lastIndexOf('%') == tS[i].length-1 && i != args.length-1)
|
||||||
|
tS[i] += "s"+tS.splice(i+1,1)[0];
|
||||||
|
nS += tS[i] + args[i];
|
||||||
|
}
|
||||||
|
return nS + tS[tS.length-1];
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detect document language settings by looking at <meta> tags.
|
||||||
|
* If no match is found, returns this.defaultLocale.
|
||||||
|
*
|
||||||
|
* @todo get by <html lang=''> - needs modification of SSViewer
|
||||||
|
*
|
||||||
|
* @return string Locale in mixed lowercase/uppercase format suitable
|
||||||
|
* for usage in ss.i18n.lang arrays (e.g. 'en_US').
|
||||||
|
*/
|
||||||
|
detectLocale: function() {
|
||||||
|
var rawLocale;
|
||||||
|
var detectedLocale;
|
||||||
|
|
||||||
|
// get by meta
|
||||||
|
$$('meta').each(function(el) {
|
||||||
|
if(el.attributes['http-equiv'] && el.attributes['http-equiv'].nodeValue.toLowerCase() == 'content-language') {
|
||||||
|
rawLocale = el.attributes['content'].nodeValue;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// fallback to default locale
|
||||||
|
if(!rawLocale) rawLocale = this.defaultLocale;
|
||||||
|
|
||||||
|
var rawLocaleParts = rawLocale.match(/([^-|_]*)[-|_](.*)/);
|
||||||
|
// get locale (e.g. 'en_US') from common name (e.g. 'en')
|
||||||
|
// by looking at ss.i18n.lang tables
|
||||||
|
if(rawLocale.length == 2) {
|
||||||
|
for(compareLocale in ss.i18n.lang) {
|
||||||
|
if(compareLocale.substr(0,2).toLowerCase() == rawLocale.toLowerCase()) {
|
||||||
|
detectedLocale = compareLocale;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(rawLocaleParts) {
|
||||||
|
detectedLocale = rawLocaleParts[1].toLowerCase() + '_' + rawLocaleParts[2].toUpperCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
var _t = function() {
|
return detectedLocale;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Event.observe(window, "load", function() {
|
||||||
|
ss.i18n.init();
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user