mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
ENHANCEMENT: Made JS i18n optional; disable it by calling Requirements::set_js_i18n(false)
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/branches/2.3@72574 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
8dc652aaa8
commit
c5ad96953a
@ -644,17 +644,20 @@ class Requirements_Backend {
|
||||
* @param $langDir The javascript lang directory, relative to the site root, e.g., 'sapphire/javascript/lang'
|
||||
*/
|
||||
public function add_i18n_javascript($langDir) {
|
||||
// Include i18n.js even if no languages are found. The fact that
|
||||
// add_i18n_javascript() was called indicates that the methods in
|
||||
// here are needed.
|
||||
$this->javascript(SAPPHIRE_DIR . '/javascript/i18n.js');
|
||||
if(i18n::get_js_i18n()) {
|
||||
// Include i18n.js even if no languages are found. The fact that
|
||||
// add_i18n_javascript() was called indicates that the methods in
|
||||
// here are needed.
|
||||
$this->javascript(SAPPHIRE_DIR . '/javascript/i18n.js');
|
||||
|
||||
if(substr($langDir,-1) != '/') $langDir .= '/';
|
||||
if(substr($langDir,-1) != '/') $langDir .= '/';
|
||||
|
||||
$defaultLangPath = $langDir . i18n::default_locale() . '.js';
|
||||
$langPath = $langDir . i18n::get_locale() . '.js';
|
||||
foreach(array($defaultLangPath, $langPath) as $path) {
|
||||
if(Director::fileExists($path)) $this->javascript($path);
|
||||
$this->javascript($langDir . i18n::default_locale() . '.js');
|
||||
$this->javascript($langDir . i18n::get_locale() . '.js');
|
||||
|
||||
// Stub i18n implementation for when i18n is disabled.
|
||||
} else {
|
||||
$this->javascript[SAPPHIRE_DIR . '/javascript/i18nx.js'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,38 @@ class i18n extends Object {
|
||||
* @var string
|
||||
*/
|
||||
protected static $default_locale = 'en_US';
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
protected static $js_i18n = true;
|
||||
|
||||
/**
|
||||
* Use javascript i18n through the ss.i18n class (enabled by default).
|
||||
* If set to TRUE, includes javascript requirements for the base library
|
||||
* (sapphire/javascript/i18n.js) and all necessary lang files (e.g. sapphire/lang/de_DE.js)
|
||||
* plus fallbacks to the default locale (e.g. sapphire/lang/en_US.js).
|
||||
* If set to FALSE, only includes a stub implementation
|
||||
* which is necessary. Mainly disabled to save bandwidth
|
||||
* in a frontend context when website is in single language.
|
||||
*
|
||||
* Caution: This flag gets overwritten in {@link LeftAndMain::init()} to enforce javascript
|
||||
* i18n for the CMS interfaces.
|
||||
*
|
||||
* @see Requirements::process_i18n_javascript()
|
||||
*
|
||||
* @param bool $bool
|
||||
*/
|
||||
public static function set_js_i18n($bool) {
|
||||
self::$js_i18n = $bool;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public static function get_js_i18n() {
|
||||
return self::$js_i18n;
|
||||
}
|
||||
|
||||
/**
|
||||
* An exhaustive list of possible locales (code => language and country)
|
||||
|
@ -84,7 +84,7 @@ HasManyFileFieldUploadButton.prototype = {
|
||||
|
||||
uploadFileQueuedCallback: function(file,queueLength) {
|
||||
var message = ss.i18n.sprintf(
|
||||
ss.i18n._t('HASMANYFILEFIELD.UPLOADING'),
|
||||
ss.i18n._t('HASMANYFILEFIELD.UPLOADING', 'Uploading... %s'),
|
||||
this.upload.getFilesToUpload()
|
||||
);
|
||||
this.parentNode.parentNode.uploadMessage.innerHTML = message;
|
||||
@ -92,7 +92,7 @@ HasManyFileFieldUploadButton.prototype = {
|
||||
|
||||
uploadFileCompleteCallback: function(file,serverData) {
|
||||
var message = ss.i18n.sprintf(
|
||||
ss.i18n._t('HASMANYFILEFIELD.UPLOADING'),
|
||||
ss.i18n._t('HASMANYFILEFIELD.UPLOADING', 'Uploading... %s'),
|
||||
this.upload.getFilesUploaded() + "/" + this.upload.getFilesToUpload()
|
||||
);
|
||||
this.parentNode.parentNode.uploadMessage.innerHTML = message;
|
||||
|
@ -75,7 +75,7 @@ TableField.prototype = {
|
||||
}
|
||||
|
||||
// TODO ajaxErrorHandler and loading-image are dependent on cms, but formfield is in sapphire
|
||||
var confirmed = confirm(ss.i18n._t('TABLEFIELD.DELETECONFIRMMESSAGE'));
|
||||
var confirmed = confirm(ss.i18n._t('TABLEFIELD.DELETECONFIRMMESSAGE', 'Are you sure you want to delete this record?'));
|
||||
if(confirmed){
|
||||
img.setAttribute("src",'cms/images/network-save.gif'); // TODO doesn't work
|
||||
new Ajax.Request(
|
||||
|
@ -84,7 +84,7 @@ TableListField.prototype = {
|
||||
var row = Event.findElement(e,"tr");
|
||||
|
||||
// TODO ajaxErrorHandler and loading-image are dependent on cms, but formfield is in sapphire
|
||||
var confirmed = confirm(ss.i18n._t('TABLEFIELD.DELETECONFIRMMESSAGE'));
|
||||
var confirmed = confirm(ss.i18n._t('TABLEFIELD.DELETECONFIRMMESSAGE', 'Are you sure you want to delete this record?'));
|
||||
if(confirmed)
|
||||
{
|
||||
img.setAttribute("src",'cms/images/network-save.gif'); // TODO doesn't work
|
||||
|
@ -67,7 +67,7 @@ TreeDropdownField.prototype = {
|
||||
}
|
||||
|
||||
this.itemTree.className = 'tree_holder';
|
||||
this.itemTree.innerHTML = ss.i18n._t('LOADING');
|
||||
this.itemTree.innerHTML = ss.i18n._t('LOADING', 'Loading...');
|
||||
this.appendChild(this.itemTree);
|
||||
}
|
||||
},
|
||||
@ -186,7 +186,7 @@ TreeDropdownField.prototype = {
|
||||
ajaxExpansion: function() {
|
||||
this.addNodeClass('loading');
|
||||
var ul = this.treeNodeHolder();
|
||||
ul.innerHTML = ss.i18n._t('LOADING');
|
||||
ul.innerHTML = ss.i18n._t('LOADING', 'Loading...');
|
||||
|
||||
var ajaxURL = this.options.dropdownField.helperURLBase() + 'getsubtree?&SubtreeRootID=' + this.getIdx();
|
||||
ajaxURL += $('SecurityID') ? '&SecurityID=' + $('SecurityID').value : '';
|
||||
|
@ -7,7 +7,7 @@ UniqueFormField.prototype = {
|
||||
if( this.restrictedValues[suggested] || suggested == null ) {
|
||||
suggested = this.suggestNewValue();
|
||||
statusMessage(ss.i18n.sprintf(
|
||||
ss.i18n._t('UNIQUEFIELD.SUGGESTED'),
|
||||
ss.i18n._t('UNIQUEFIELD.SUGGESTED', "Changed value to '%s' : %s"),
|
||||
suggested,
|
||||
this.restrictedMessage
|
||||
));
|
||||
@ -112,9 +112,9 @@ UniqueRestrictedTextField.prototype = {
|
||||
if( suggested == null || suggested.length == 0 || suggestedValue || suggested.match( this.charRegex ) ) {
|
||||
var message;
|
||||
if( suggested == null )
|
||||
message = ss.i18n._t('UNIQUEFIELD.ENTERNEWVALUE');
|
||||
message = ss.i18n._t('UNIQUEFIELD.ENTERNEWVALUE', 'You will need to enter a new value for this field');
|
||||
else if( suggested.length == 0 )
|
||||
message = ss.i18n._t('UNIQUEFIELD.CANNOTLEAVEEMPTY');
|
||||
message = ss.i18n._t('UNIQUEFIELD.CANNOTLEAVEEMPTY', 'This field cannot be left empty');
|
||||
else if( suggestedValue )
|
||||
message = this.restrictedMessage;
|
||||
else
|
||||
@ -122,7 +122,7 @@ UniqueRestrictedTextField.prototype = {
|
||||
|
||||
suggested = this.suggestNewValue();
|
||||
statusMessage(ss.i18n.sprintf(
|
||||
ss.i18n._t('UNIQUEFIELD.SUGGESTED'),
|
||||
ss.i18n._t('UNIQUEFIELD.SUGGESTED', "Changed value to '%s' : %s"),
|
||||
suggested,
|
||||
message
|
||||
));
|
||||
@ -152,7 +152,7 @@ RestrictedTextField.prototype = {
|
||||
for( var index = 0; index < this.restrictedChars.length; index++ ) {
|
||||
if( lastChar == this.restrictedChars.charAt(index) ) {
|
||||
alert(ss.i18n.sprintf(
|
||||
ss.i18n._t('RESTRICTEDTEXTFIELD.CHARCANTBEUSED'),
|
||||
ss.i18n._t('RESTRICTEDTEXTFIELD.CHARCANTBEUSED', "The character '%s' cannot be used in this field"),
|
||||
lastChar
|
||||
));
|
||||
this.value = this.value.substring( 0, this.value.length - 1 );
|
||||
|
@ -11,7 +11,7 @@ Behaviour.register({
|
||||
var newSuggestion = urlSegmentField.suggestNewValue( this.value.toLowerCase() );
|
||||
var isNew = urlSegmentField.value.indexOf("new") == 0;
|
||||
var confirmMessage = ss.i18n.sprintf(
|
||||
ss.i18n._t('UPDATEURL.CONFIRM'),
|
||||
ss.i18n._t('UPDATEURL.CONFIRM', 'Would you like me to change the URL to:\n\n%s/\n\nClick Ok to change the URL, click Cancel to leave it as:\n\n%s'),
|
||||
newSuggestion,
|
||||
urlSegmentField.value
|
||||
);
|
||||
|
@ -147,7 +147,7 @@ function require(fieldName,cachedError) {
|
||||
fieldlabel = "this field";
|
||||
}
|
||||
|
||||
var errorMessage = ss.i18n.sprintf(ss.i18n._t('VALIDATOR.FIELDREQUIRED'), fieldLabel);
|
||||
var errorMessage = ss.i18n.sprintf(ss.i18n._t('VALIDATOR.FIELDREQUIRED', 'Please fill out "%s", it is required.'), fieldLabel);
|
||||
if(baseEl.requiredErrorMsg) errorMessage = baseEl.requiredErrorMsg;
|
||||
else if(_CURRENT_FORM.requiredErrorMsg) errorMessage = _CURRENT_FORM.requiredErrorMsg;
|
||||
|
||||
|
@ -4,10 +4,10 @@ if(typeof(ss) == 'undefined') ss = {};
|
||||
* Lightweight clientside i18n implementation.
|
||||
* Caution: Only available after DOM loaded because we need to detect the language
|
||||
*
|
||||
* For non-i18n stub implementation, see sapphire/javascript/i18nx.js
|
||||
*
|
||||
* 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
|
||||
@ -51,8 +51,8 @@ ss.i18n = {
|
||||
* 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 string entity A "long" locale format, e.g. "de_DE" (Required)
|
||||
* @param string fallbackString (Required)
|
||||
* @param int priority (not used)
|
||||
* @param string context Give translators context for the string
|
||||
* @return string : Translated word
|
||||
|
40
javascript/i18nx.js
Normal file
40
javascript/i18nx.js
Normal file
@ -0,0 +1,40 @@
|
||||
if(typeof(ss) == 'undefined') ss = {};
|
||||
|
||||
/**
|
||||
* Stub implementation for ss.i18n code.
|
||||
* Use instead of sapphire/javascript/i18n.js
|
||||
* if you want to use any SilverStripe javascript
|
||||
* without internationalization support.
|
||||
*/
|
||||
ss.i18n = {
|
||||
currentLocale: 'en_US',
|
||||
|
||||
defaultLocale: 'en_US',
|
||||
|
||||
_t: function (entity, fallbackString, priority, context) {
|
||||
return fallbackString;
|
||||
},
|
||||
|
||||
sprintf: 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];
|
||||
},
|
||||
|
||||
// stub methods
|
||||
addDictionary: function() {},
|
||||
getDictionary: function() {}
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user