diff --git a/install.sh b/install.sh
index 6a9cccc32a..02c1626db8 100755
--- a/install.sh
+++ b/install.sh
@@ -247,6 +247,9 @@ SUNSTONE_DIRS="$SUNSTONE_LOCATION/models \
$SUNSTONE_LOCATION/public/js/plugins \
$SUNSTONE_LOCATION/public/js/user-plugins \
$SUNSTONE_LOCATION/public/css \
+ $SUNSTONE_LOCATION/public/locale \
+ $SUNSTONE_LOCATION/public/locale/en_US \
+ $SUNSTONE_LOCATION/public/locale/ru \
$SUNSTONE_LOCATION/public/vendor \
$SUNSTONE_LOCATION/public/vendor/jQueryLayout \
$SUNSTONE_LOCATION/public/vendor/dataTables \
@@ -417,6 +420,8 @@ INSTALL_SUNSTONE_FILES=(
SUNSTONE_PUBLIC_VENDOR_JQUERYLAYOUT:$SUNSTONE_LOCATION/public/vendor/jQueryLayout
SUNSTONE_PUBLIC_VENDOR_FLOT:$SUNSTONE_LOCATION/public/vendor/flot
SUNSTONE_PUBLIC_IMAGES_FILES:$SUNSTONE_LOCATION/public/images
+ SUNSTONE_PUBLIC_LOCALE_EN_US:$SUNSTONE_LOCATION/public/locale/en_US
+ SUNSTONE_PUBLIC_LOCALE_RU:$SUNSTONE_LOCATION/public/locale/ru
)
INSTALL_SUNSTONE_ETC_FILES=(
@@ -1001,7 +1006,8 @@ SUNSTONE_PUBLIC_JS_FILES="src/sunstone/public/js/layout.js \
src/sunstone/public/js/login.js \
src/sunstone/public/js/sunstone.js \
src/sunstone/public/js/sunstone-util.js \
- src/sunstone/public/js/opennebula.js"
+ src/sunstone/public/js/opennebula.js \
+ src/sunstone/public/js/locale.js"
SUNSTONE_PUBLIC_JS_PLUGINS_FILES="\
src/sunstone/public/js/plugins/dashboard-tab.js \
@@ -1082,6 +1088,14 @@ SUNSTONE_PUBLIC_IMAGES_FILES="src/sunstone/public/images/ajax-loader.gif \
src/sunstone/public/images/vnc_off.png \
src/sunstone/public/images/vnc_on.png"
+SUNSTONE_PUBLIC_LOCALE_EN_US=""
+
+SUNSTONE_PUBLIC_LOCALE_RU="
+src/sunstone/public/locale/ru/ru.js \
+src/sunstone/public/locale/ru/ru_datatable.txt"
+
+
+
#-----------------------------------------------------------------------------
# Ozones files
#-----------------------------------------------------------------------------
@@ -1141,7 +1155,8 @@ OZONES_PUBLIC_JS_FILES="src/ozones/Server/public/js/ozones.js \
src/ozones/Server/public/js/ozones-util.js \
src/sunstone/public/js/layout.js \
src/sunstone/public/js/sunstone.js \
- src/sunstone/public/js/sunstone-util.js"
+ src/sunstone/public/js/sunstone-util.js \
+ src/sunstone/public/js/locale.js"
OZONES_PUBLIC_CSS_FILES="src/ozones/Server/public/css/application.css \
src/ozones/Server/public/css/layout.css \
diff --git a/src/sunstone/etc/sunstone-server.conf b/src/sunstone/etc/sunstone-server.conf
index 2311501782..4993e571d9 100644
--- a/src/sunstone/etc/sunstone-server.conf
+++ b/src/sunstone/etc/sunstone-server.conf
@@ -20,3 +20,6 @@
# VNC Configuration
:vnc_proxy_base_port: 29876
:novnc_path:
+
+# Default language setting
+:lang: en_US
\ No newline at end of file
diff --git a/src/sunstone/models/OpenNebulaJSON/UserJSON.rb b/src/sunstone/models/OpenNebulaJSON/UserJSON.rb
index 726845d23c..a2d89476a4 100644
--- a/src/sunstone/models/OpenNebulaJSON/UserJSON.rb
+++ b/src/sunstone/models/OpenNebulaJSON/UserJSON.rb
@@ -64,7 +64,7 @@ module OpenNebulaJSON
end
def update(params=Hash.new)
- super(params['raw_template'])
+ super(params['template_raw'])
end
def addgroup(params=Hash.new)
diff --git a/src/sunstone/public/css/layout.css b/src/sunstone/public/css/layout.css
index f5fbf16d98..63630c8911 100644
--- a/src/sunstone/public/css/layout.css
+++ b/src/sunstone/public/css/layout.css
@@ -169,3 +169,15 @@ background-image: -moz-linear-gradient(
#navigation li:hover a, .navigation-active-li-a {
color: #ffffff !important;
}
+
+#language {
+ float:right;
+ margin-top:2px;
+ margin-right:25px;
+ width: 100px;
+}
+
+#language select {
+ width: 100px;
+ height: 22px;
+}
diff --git a/src/sunstone/public/js/locale.js b/src/sunstone/public/js/locale.js
new file mode 100644
index 0000000000..5aa681fe6c
--- /dev/null
+++ b/src/sunstone/public/js/locale.js
@@ -0,0 +1,48 @@
+var lang=""
+var locale = {};
+var datatable_lang = "";
+
+function tr(str){
+ var tmp = locale[str];
+ if ( tmp == null || tmp == "" ) {
+ //console.debug("trans: "+str);
+ tmp = str;
+ }
+ return tmp;
+};
+
+function setLang(lang_str){
+ $('
Loading new language... please wait '+spinner+'
').dialog({
+ draggable:false,
+ modal:true,
+ resizable:false,
+ buttons:{},
+ width: 460,
+ minHeight: 50
+
+ });
+
+ var template = "LANG="+lang_str;
+ var obj = {
+ data: {
+ id: uid,
+ extra_param: template
+ },
+ error: onError
+ };
+ OpenNebula.User.update(obj);
+ $.post('config',JSON.stringify({lang:lang_str}),refreshLang);
+};
+
+function refreshLang(){
+ window.location.href = ".";
+};
+
+$(document).ready(function(){
+ if (lang)
+ $('#lang_sel option[value="'+lang+'"]').attr("selected","selected");
+ $('#lang_sel').change(function(){
+ setLang($(this).val());
+ });
+
+});
\ No newline at end of file
diff --git a/src/sunstone/public/js/plugins/acls-tab.js b/src/sunstone/public/js/plugins/acls-tab.js
index ad94ffd2b6..3dfd077b6d 100644
--- a/src/sunstone/public/js/plugins/acls-tab.js
+++ b/src/sunstone/public/js/plugins/acls-tab.js
@@ -25,12 +25,12 @@ var acls_tab_content =
\
\
\
- Summary of resources\
+ '+tr('Summary of resources')+'\
\
\
\
\
- VM Templates (total/public) | \
+ '+tr('VM Templates (total/public)')+' | \
| \
\
\
- VM Instances (total/running/failed) | \
+ '+tr('VM Instances')+' ('+tr('total')+'/'+tr('running')+'/'+tr('failed')+') | \
| \
\
\
- Virtual Networks (total/public) | \
+ '+tr('Virtual Networks (total/public)')+' | \
| \
\
\
- Images (total/public) | \
+ '+tr('Images (total/public)')+' | \
| \
\
\
@@ -79,14 +79,14 @@ var dashboard_tab_content =
\
\
\
- Quickstart\
+ '+tr('Quickstart')+'\
\
| \
@@ -98,19 +98,19 @@ var dashboard_tab_content =
\
\
\
- Historical monitoring information\
+ '+tr('Historical monitoring information')+'\
\
\
- Total VM count | \
+ '+tr('Total VM count')+' | \
| \
'+spinner+' | \
- Total VM CPU | \
+ '+tr('Total VM CPU')+' | \
| \
'+spinner+' | \
- Total VM Memory | \
+ '+tr('Total VM Memory')+' | \
| \
'+spinner+' | \
- VM Network stats | \
+ '+tr('VM Network stats')+' | \
| \
'+spinner+' | \
\
@@ -123,7 +123,7 @@ var dashboard_tab_content =
| ';
var dashboard_tab = {
- title: 'Dashboard',
+ title: tr('Dashboard'),
content: dashboard_tab_content
}
diff --git a/src/sunstone/public/js/plugins/groups-tab.js b/src/sunstone/public/js/plugins/groups-tab.js
index 0f1b39a5c9..caea4ff5bb 100644
--- a/src/sunstone/public/js/plugins/groups-tab.js
+++ b/src/sunstone/public/js/plugins/groups-tab.js
@@ -25,10 +25,10 @@ var groups_tab_content =
\
\
\
- All | \
- ID | \
- Name | \
- Users | \
+ '+tr("All")+' | \
+ '+tr("ID")+' | \
+ '+tr("Name")+' | \
+ '+tr("Users")+' | \
\
\
\
@@ -40,14 +40,14 @@ var create_group_tmpl =
'';
@@ -118,12 +118,12 @@ var group_actions = {
var group_buttons = {
"Group.refresh" : {
type: "image",
- text: "Refresh list",
+ text: tr("Refresh list"),
img: "images/Refresh-icon.png"
},
"Group.create_dialog" : {
type: "create_dialog",
- text: "+ New Group"
+ text: tr("+ New Group")
},
// "Group.chown" : {
// type: "confirm_with_select",
@@ -135,12 +135,12 @@ var group_buttons = {
"Group.delete" : {
type: "action",
- text: "Delete"
+ text: tr("Delete")
}
};
var groups_tab = {
- title: 'Groups',
+ title: tr("Groups"),
content: groups_tab_content,
buttons: group_buttons
}
@@ -228,7 +228,7 @@ function updateGroupsView(request, group_list){
//Prepares the dialog to create
function setupCreateGroupDialog(){
- dialogs_context.append('');
+ dialogs_context.append('');
$create_group_dialog = $('#create_group_dialog',dialogs_context);
var dialog = $create_group_dialog;
@@ -276,7 +276,11 @@ $(document).ready(function(){
{ "bSortable": false, "aTargets": ["check"] },
{ "sWidth": "60px", "aTargets": [0] },
{ "sWidth": "35px", "aTargets": [1] }
- ]
+ ],
+ "oLanguage": (datatable_lang != "") ?
+ {
+ sUrl: "locale/"+lang+"/"+datatable_lang
+ } : ""
});
dataTable_groups.fnClearTable();
diff --git a/src/sunstone/public/js/plugins/hosts-tab.js b/src/sunstone/public/js/plugins/hosts-tab.js
index c54d9a78d9..98b3a07ea8 100644
--- a/src/sunstone/public/js/plugins/hosts-tab.js
+++ b/src/sunstone/public/js/plugins/hosts-tab.js
@@ -19,13 +19,13 @@
var HOST_HISTORY_LENGTH = 40;
var host_graphs = [
{
- title : "CPU Monitoring information",
+ title : tr("CPU Monitoring information"),
monitor_resources : "cpu_usage,used_cpu,max_cpu",
humanize_figures : false,
history_length : HOST_HISTORY_LENGTH
},
{
- title: "Memory monitoring information",
+ title: tr("Memory monitoring information"),
monitor_resources : "mem_usage,used_mem,max_mem",
humanize_figures : true,
history_length : HOST_HISTORY_LENGTH
@@ -40,13 +40,13 @@ var hosts_tab_content =
\
\
\
- All | \
- ID | \
- Name | \
- Running VMs | \
- CPU Use | \
- Memory use | \
- Status | \
+ ' + tr('All') + ' | \
+ ' + tr('id') + ' | \
+ ' + tr('Name') + ' | \
+ ' + tr('Running VMs') + ' | \
+ ' + tr('CPU Use') + ' | \
+ ' + tr('Memory use') + ' | \
+ ' + tr('Status') + ' | \
\
\
\
@@ -57,42 +57,42 @@ var hosts_tab_content =
var create_host_tmpl =
'';
@@ -233,7 +233,7 @@ var host_actions = {
type: "single",
call: OpenNebula.Host.update,
callback: function() {
- notifyMessage("Template updated correctly");
+ notifyMessage(tr("Template updated correctly"));
},
error: onError
}
@@ -242,51 +242,51 @@ var host_actions = {
var host_buttons = {
"Host.refresh" : {
type: "image",
- text: "Refresh list",
+ text: tr("Refresh list"),
img: "images/Refresh-icon.png"
},
"Host.create_dialog" : {
type: "create_dialog",
- text: "+ New"
+ text: tr("+ New")
},
"Host.update_dialog" : {
type: "action",
- text: "Update a template",
+ text: tr("Update a template"),
alwaysActive: true
},
"Host.enable" : {
type: "action",
- text: "Enable"
+ text: tr("Enable")
},
"Host.disable" : {
type: "action",
- text: "Disable"
+ text: tr("Disable")
},
"Host.delete" : {
type: "action",
- text: "Delete host"
+ text: tr("Delete host")
}
};
var host_info_panel = {
"host_info_tab" : {
- title: "Host information",
+ title: tr("Host information"),
content:""
},
"host_template_tab" : {
- title: "Host template",
+ title: tr("Host template"),
content: ""
},
"host_monitoring_tab": {
- title: "Monitoring information",
+ title: tr("Monitoring information"),
content: ""
}
};
var hosts_tab = {
- title: 'Hosts',
+ title: tr('Hosts'),
content: hosts_tab_content,
buttons: host_buttons
}
@@ -420,62 +420,62 @@ function updateHostInfo(request,host){
//Information tab
var info_tab = {
- title : "Host information",
+ title : tr("Host information"),
content :
'\
\
- Host information - '+host_info.NAME+' | \
+ ' + tr('Host information') + ' - '+host_info.NAME+' | \
\
\
\
- ID | \
+ ' + tr('id') + ' | \
'+host_info.ID+' | \
\
\
- State | \
- '+OpenNebula.Helper.resource_state("host",host_info.STATE)+' | \
+ ' + tr('State') + ' | \
+ '+tr(OpenNebula.Helper.resource_state("host",host_info.STATE))+' | \
\
\
- IM MAD | \
+ ' + tr('IM MAD') + ' | \
'+host_info.IM_MAD+' | \
\
\
- VM MAD | \
+ ' + tr('VM MAD') + ' | \
'+host_info.VM_MAD+' | \
\
\
- TM MAD | \
+ ' + tr('TM MAD') + ' | \
'+host_info.TM_MAD+' | \
\
\
\
\
\
- Host shares | \
+ ' + tr('Host shares') + ' | \
\
\
\
- Max Mem | \
+ ' + tr('Max Mem') + ' | \
'+humanize_size(host_info.HOST_SHARE.MAX_MEM)+' | \
\
\
- Used Mem (real) | \
+ ' + tr('Used Mem (real)') + ' | \
'+humanize_size(host_info.HOST_SHARE.USED_MEM)+' | \
\
\
- Used Mem (allocated) | \
+ ' + tr('Used Mem (allocated)') + ' | \
'+humanize_size(host_info.HOST_SHARE.MAX_USAGE)+' | \
\
\
- Used CPU (real) | \
+ ' + tr('Used CPU (real)') + ' | \
'+host_info.HOST_SHARE.USED_CPU+' | \
\
\
- Used CPU (allocated) | \
+ ' + tr('Used CPU (allocated)') + ' | \
'+host_info.HOST_SHARE.CPU_USAGE+' | \
\
\
- Running VMs | \
+ ' + tr('Running VMs') + ' | \
'+host_info.HOST_SHARE.RUNNING_VMS+' | \
\
\
@@ -484,16 +484,16 @@ function updateHostInfo(request,host){
//Template tab
var template_tab = {
- title : "Host template",
+ title : tr("Host template"),
content :
'\
- Host template | '+
+ ' + tr('Host template') + ' | '+
prettyPrintJSON(host_info.TEMPLATE)+
' '
}
var monitor_tab = {
- title: "Monitoring information",
+ title: tr("Monitoring information"),
content : generateMonitoringDivs(host_graphs,"host_monitor_")
}
@@ -513,7 +513,7 @@ function updateHostInfo(request,host){
//Prepares the host creation dialog
function setupCreateHostDialog(){
- dialogs_context.append('');
+ dialogs_context.append('');
$create_host_dialog = $('div#create_host_dialog');
var dialog = $create_host_dialog;
@@ -529,7 +529,7 @@ function setupCreateHostDialog(){
//Handle the form submission
$('#create_host_form',dialog).submit(function(){
if (!($('#name',this).val().length)){
- notifyError("Host name missing!");
+ notifyError(tr("Host name missing!"));
return false;
}
var host_json = {
@@ -596,7 +596,11 @@ $(document).ready(function(){
{ "sWidth": "35px", "aTargets": [1] },
{ "sWidth": "100px", "aTargets": [6] },
{ "sWidth": "200px", "aTargets": [4,5] }
- ]
+ ],
+ "oLanguage": (datatable_lang != "") ?
+ {
+ sUrl: "locale/"+lang+"/"+datatable_lang
+ } : ""
});
//preload it
diff --git a/src/sunstone/public/js/plugins/images-tab.js b/src/sunstone/public/js/plugins/images-tab.js
index d8fd88bac8..2ec58f4cd6 100644
--- a/src/sunstone/public/js/plugins/images-tab.js
+++ b/src/sunstone/public/js/plugins/images-tab.js
@@ -23,18 +23,18 @@ var images_tab_content =
|