diff --git a/install.sh b/install.sh
index 048ef1b526..b2b2f080f6 100755
--- a/install.sh
+++ b/install.sh
@@ -253,6 +253,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 \
@@ -426,6 +429,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=(
@@ -1046,7 +1051,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 \
@@ -1058,7 +1064,8 @@ SUNSTONE_PUBLIC_JS_PLUGINS_FILES="\
src/sunstone/public/js/plugins/users-tab.js \
src/sunstone/public/js/plugins/vms-tab.js \
src/sunstone/public/js/plugins/acls-tab.js \
- src/sunstone/public/js/plugins/vnets-tab.js"
+ src/sunstone/public/js/plugins/vnets-tab.js \
+ src/sunstone/public/js/plugins/config-tab.js"
SUNSTONE_PUBLIC_CSS_FILES="src/sunstone/public/css/application.css \
src/sunstone/public/css/layout.css \
@@ -1129,6 +1136,16 @@ SUNSTONE_PUBLIC_IMAGES_FILES="src/sunstone/public/images/ajax-loader.gif \
src/sunstone/public/images/green_bullet.png \
src/sunstone/public/images/vnc_off.png \
src/sunstone/public/images/vnc_on.png"
+
+SUNSTONE_PUBLIC_LOCALE_EN_US="\
+src/sunstone/public/locale/en_US/en_US.js \
+"
+
+SUNSTONE_PUBLIC_LOCALE_RU="
+src/sunstone/public/locale/ru/ru.js \
+src/sunstone/public/locale/ru/ru_datatable.txt"
+
+
#-----------------------------------------------------------------------------
# Ozones files
@@ -1189,8 +1206,9 @@ 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 \
src/ozones/Server/public/css/login.css"
diff --git a/src/sunstone/etc/sunstone-plugins.yaml b/src/sunstone/etc/sunstone-plugins.yaml
index 38228d404e..ce33cfff64 100644
--- a/src/sunstone/etc/sunstone-plugins.yaml
+++ b/src/sunstone/etc/sunstone-plugins.yaml
@@ -45,3 +45,7 @@
:user:
:group:
oneadmin: true
+- plugins/config-tab.js:
+ :ALL: true
+ :user:
+ :group:
diff --git a/src/sunstone/etc/sunstone-server.conf b/src/sunstone/etc/sunstone-server.conf
index 4391ca8a5f..1927bfb949 100644
--- a/src/sunstone/etc/sunstone-server.conf
+++ b/src/sunstone/etc/sunstone-server.conf
@@ -17,4 +17,7 @@
# VNC Configuration
:vnc_proxy_base_port: 29876
-:novnc_path:
+:novnc_path:
+
+# Default language setting
+:lang: en_US
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/js/locale.js b/src/sunstone/public/js/locale.js
new file mode 100644
index 0000000000..d5b1e970c5
--- /dev/null
+++ b/src/sunstone/public/js/locale.js
@@ -0,0 +1,88 @@
+/* -------------------------------------------------------------------------- */
+/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
+/* not use this file except in compliance with the License. You may obtain */
+/* a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
+/* See the License for the specific language governing permissions and */
+/* limitations under the License. */
+/* -------------------------------------------------------------------------- */
+
+var lang=""
+var locale = {};
+var datatable_lang = "";
+
+function tr(str){
+ var tmp = locale[str];
+ if ( tmp == null || tmp == "" ) {
+ //console.debug("Missing translation: "+str);
+ tmp = str;
+ }
+ return tmp;
+};
+
+//Pops up loading new language dialog. Retrieves the user template, updates the LANG variable.
+//Updates template and session configuration and reloads the view.
+function setLang(lang_str){
+ var lang_tmp="";
+ var dialog = $('
'+tr("Loading new language... please wait")+' '+spinner+'
').dialog({
+ draggable:false,
+ modal:true,
+ resizable:false,
+ buttons:{},
+ width: 460,
+ minHeight: 50
+
+ });
+
+ var updateUserTemplate = function(request,user_json){
+ var template = user_json.USER.TEMPLATE;
+ var template_str="";
+ template["LANG"] = lang_tmp;
+
+ //convert json to ONE template format - simple conversion
+ $.each(template,function(key,value){
+ template_str += (key + '=' + '"' + value + '"\n');
+ });
+
+ var obj = {
+ data: {
+ id: uid,
+ extra_param: template_str
+ },
+ error: onError
+ };
+ OpenNebula.User.update(obj);
+ $.post('config',JSON.stringify({lang:lang_tmp}),function(){window.location.href = "."});
+
+ };
+
+ lang_tmp = lang_str;
+
+ if (whichUI() == "sunstone"){
+ var obj = {
+ data : {
+ id: uid,
+ },
+ success: updateUserTemplate
+ };
+ OpenNebula.User.show(obj);
+ } else {
+ dialog.dialog('close');
+ };
+};
+
+$(document).ready(function(){
+ //Update static translations
+ $('#doc_link').text(tr("Documentation"));
+ $('#support_link').text(tr("Support"));
+ $('#community_link').text(tr("Community"));
+ $('#welcome').text(tr("Welcome"));
+ $('#logout').text(tr("Sign out"));
+});
\ 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..f0515f0bcb 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 +82,14 @@ var dashboard_tab_content =
\
\
\
- Quickstart\
+ '+tr("Quickstart")+'\
\
| \
@@ -98,19 +101,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 +126,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..1a31960052 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;
@@ -259,7 +259,7 @@ function popUpCreateGroupDialog(){
function setGroupAutorefresh(){
setInterval(function(){
var checked = $('input.check_item:checked',dataTable_groups);
- var filter = $("#datatable_groups_filter input",dataTable_groups.parents("#datatable_groups_wrapper")).attr("value");
+ var filter = $("#datatable_groups_filter input",dataTable_groups.parents("#datatable_groups_wrapper")).attr('value');
if (!checked.length && !filter.length){
Sunstone.runAction("Group.autorefresh");
}
@@ -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 76e0a9591d..48c6802dcf 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,27 +57,27 @@ var hosts_tab_content =
var create_host_tmpl =
'';
@@ -243,7 +243,7 @@ var host_actions = {
type: "single",
call: OpenNebula.Host.update,
callback: function() {
- notifyMessage("Template updated correctly");
+ notifyMessage(tr("Template updated correctly"));
},
error: onError
}
@@ -252,51 +252,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
}
@@ -430,66 +430,66 @@ 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+' | \
\
\
- VN MAD | \
+ '+ tr("VN MAD") +' | \
'+host_info.VN_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+' | \
\
\
@@ -498,16 +498,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_")
}
@@ -527,7 +527,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;
@@ -543,7 +543,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 = {
@@ -574,7 +574,7 @@ function popUpCreateHostDialog(){
function setHostAutorefresh() {
setInterval(function(){
var checked = $('input.check_item:checked',dataTable_hosts);
- var filter = $("#datatable_hosts_filter input",dataTable_hosts.parents('#datatable_hosts_wrapper')).attr("value");
+ var filter = $("#datatable_hosts_filter input",dataTable_hosts.parents('#datatable_hosts_wrapper')).attr('value');
if (!checked.length && !filter.length){
Sunstone.runAction("Host.autorefresh");
}
@@ -611,7 +611,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 ce879dee85..4a1583ce3a 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 =
|