[PATCH V4 0/7] Issue #342: load i18n.html of the plugin

From: ShaoHe Feng <shaohef@linux.vnet.ibm.com> V3 -> V4: rebase V2 -> V3: change "enable-plugins" to "enable-sample" remove nls improve the Portuguese translation. V1 -> V2: The improvement concept here is to directly generate JSON on the server and assign it to the i18n variable, rather than inserting nodes into the DOM. Plugins would use a plugin1.i18n= structure to keep plugin strings from colliding with each other, or with the kimchi variables. ShaoHe Feng (6): Update root.py to make Cheetah render the JSON template. Update the i18n tmpl to produce JSON Add JS API for fetching i18n JSON Issue #342: load i18n.html of the plugin add an optional to toggle the sample plugin generate the translation files for plugins/sample Zhou Zheng Sheng (1): Add Minimal UI Page for the Sample Plugin configure.ac | 11 ++ plugins/sample/Makefile.am | 26 ++++- plugins/sample/__init__.py | 3 +- plugins/sample/config.status | 1 + plugins/sample/po/LINGUAS | 1 + plugins/sample/po/Makefile.in.in | 1 + plugins/sample/po/Makevars | 1 + plugins/sample/po/POTFILES.in | 2 + plugins/sample/po/en_US.po | 21 ++++ plugins/sample/po/gen-pot | 1 + plugins/sample/po/pt_BR.po | 24 +++++ plugins/sample/po/zh_CN.po | 24 +++++ plugins/sample/sample.conf | 7 -- plugins/sample/sample.conf.in | 12 +++ plugins/sample/ui/config/tab-ext.xml | 8 +- plugins/sample/ui/pages/i18n.json.tmpl | 9 ++ plugins/sample/ui/pages/tab.html.tmpl | 6 ++ src/kimchi/root.py | 5 + src/kimchi/template.py | 34 ++++--- ui/js/src/kimchi.api.js | 18 +++- ui/js/src/kimchi.main.js | 24 ++++- ui/pages/i18n.html.tmpl | 178 --------------------------------- ui/pages/i18n.json.tmpl | 165 ++++++++++++++++++++++++++++++ 23 files changed, 369 insertions(+), 213 deletions(-) create mode 120000 plugins/sample/config.status create mode 120000 plugins/sample/po/LINGUAS create mode 120000 plugins/sample/po/Makefile.in.in create mode 120000 plugins/sample/po/Makevars create mode 100644 plugins/sample/po/POTFILES.in create mode 100644 plugins/sample/po/en_US.po create mode 120000 plugins/sample/po/gen-pot create mode 100644 plugins/sample/po/pt_BR.po create mode 100644 plugins/sample/po/zh_CN.po delete mode 100644 plugins/sample/sample.conf create mode 100644 plugins/sample/sample.conf.in create mode 100644 plugins/sample/ui/pages/i18n.json.tmpl create mode 100644 plugins/sample/ui/pages/tab.html.tmpl delete mode 100644 ui/pages/i18n.html.tmpl create mode 100644 ui/pages/i18n.json.tmpl -- 1.9.3

From: Zhou Zheng Sheng <zhshzhou@linux.vnet.ibm.com> Add minimal UI just enough to re-produce issue 342. https://github.com/kimchi-project/kimchi/issues/342 Signed-off-by: Zhou Zheng Sheng <zhshzhou@linux.vnet.ibm.com> Signed-off-by: ShaoHe Feng <shaohef@linux.vnet.ibm.com> --- plugins/sample/__init__.py | 3 ++- plugins/sample/sample.conf | 5 +++++ plugins/sample/ui/config/tab-ext.xml | 8 ++++---- plugins/sample/ui/pages/i18n.json.tmpl | 9 +++++++++ plugins/sample/ui/pages/tab.html.tmpl | 6 ++++++ 5 files changed, 26 insertions(+), 5 deletions(-) create mode 100644 plugins/sample/ui/pages/i18n.json.tmpl create mode 100644 plugins/sample/ui/pages/tab.html.tmpl diff --git a/plugins/sample/__init__.py b/plugins/sample/__init__.py index 3183898..2101aed 100644 --- a/plugins/sample/__init__.py +++ b/plugins/sample/__init__.py @@ -26,6 +26,7 @@ from kimchi.config import PluginPaths from kimchi.control.base import Collection, Resource +from kimchi.root import Root from plugins.sample.i18n import messages from plugins.sample.model import Model @@ -33,7 +34,7 @@ model = Model() -class Drawings(Resource): +class Drawings(Root): def __init__(self): Resource.__init__(self, model) self.description = Description(model) diff --git a/plugins/sample/sample.conf b/plugins/sample/sample.conf index c4e80f7..78a9f4e 100644 --- a/plugins/sample/sample.conf +++ b/plugins/sample/sample.conf @@ -5,3 +5,8 @@ uri = "/plugins/sample" [/] tools.trailing_slash.on = False +tools.sessions.on = True +tools.sessions.name = 'kimchi' +tools.sessions.httponly = True +tools.sessions.locking = 'explicit' +tools.sessions.storage_type = 'ram' diff --git a/plugins/sample/ui/config/tab-ext.xml b/plugins/sample/ui/config/tab-ext.xml index 948fa07..8e0b3d3 100644 --- a/plugins/sample/ui/config/tab-ext.xml +++ b/plugins/sample/ui/config/tab-ext.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> -<!--<tabs-ext> +<tabs-ext> <tab> - <title>Test</title> - <filePath>plugins/sample/ui/tab.html</filePath> + <title>SampleTab</title> + <path>plugins/sample/tab.html</path> </tab> -</tabs-ext>--> \ No newline at end of file +</tabs-ext> diff --git a/plugins/sample/ui/pages/i18n.json.tmpl b/plugins/sample/ui/pages/i18n.json.tmpl new file mode 100644 index 0000000..a153e2d --- /dev/null +++ b/plugins/sample/ui/pages/i18n.json.tmpl @@ -0,0 +1,9 @@ +#unicode UTF-8 +#import gettext +#from kimchi.cachebust import href +#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang) +#silent _ = t.gettext +#silent _t = t.gettext +{ + "SampleTab": "$_("SampleTab")" +} diff --git a/plugins/sample/ui/pages/tab.html.tmpl b/plugins/sample/ui/pages/tab.html.tmpl new file mode 100644 index 0000000..49fc4ec --- /dev/null +++ b/plugins/sample/ui/pages/tab.html.tmpl @@ -0,0 +1,6 @@ +<!DOCTYPE html> +<html> +<body> +Hello, world +</body> +</html> -- 1.9.3

From: ShaoHe Feng <shaohef@linux.vnet.ibm.com> when the request are json files, set the Content-Type as application/json. Signed-off-by: Adam King <rak@linux.vnet.ibm.com> Signed-off-by: ShaoHe Feng <shaohef@linux.vnet.ibm.com> --- src/kimchi/root.py | 5 +++++ src/kimchi/template.py | 34 +++++++++++++++++++--------------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/kimchi/root.py b/src/kimchi/root.py index 8b1d09b..1cebfd1 100644 --- a/src/kimchi/root.py +++ b/src/kimchi/root.py @@ -82,6 +82,11 @@ def get(self): def default(self, page, **kwargs): if page.endswith('.html'): return template.render(page, None) + if page.endswith('.json'): + cherrypy.response.headers['Content-Type'] = \ + 'application/json;charset=utf-8' + context = template.render_cheetah_file(page, None) + return context.encode("utf-8") raise cherrypy.HTTPError(404) @cherrypy.expose diff --git a/src/kimchi/template.py b/src/kimchi/template.py index 60cd818..146e735 100644 --- a/src/kimchi/template.py +++ b/src/kimchi/template.py @@ -82,26 +82,30 @@ def can_accept_html(): can_accept('*/*') +def render_cheetah_file(resource, data): + paths = cherrypy.request.app.root.paths + filename = paths.get_template_path(resource) + try: + params = {'data': data} + lang = validate_language(get_lang()) + gettext_conf = {'domain': 'kimchi', + 'localedir': paths.mo_dir, + 'lang': [lang]} + params['lang'] = gettext_conf + return Template(file=filename, searchList=params).respond() + except OSError, e: + if e.errno == errno.ENOENT: + raise cherrypy.HTTPError(404) + else: + raise + + def render(resource, data): if can_accept('application/json'): cherrypy.response.headers['Content-Type'] = \ 'application/json;charset=utf-8' return json.dumps(data, indent=2, separators=(',', ':')) elif can_accept_html(): - paths = cherrypy.request.app.root.paths - filename = paths.get_template_path(resource) - try: - params = {'data': data} - lang = validate_language(get_lang()) - gettext_conf = {'domain': 'kimchi', - 'localedir': paths.mo_dir, - 'lang': [lang]} - params['lang'] = gettext_conf - return Template(file=filename, searchList=params).respond() - except OSError, e: - if e.errno == errno.ENOENT: - raise cherrypy.HTTPError(404) - else: - raise + return render_cheetah_file(resource, data) else: raise cherrypy.HTTPError(406) -- 1.9.3

From: ShaoHe Feng <shaohef@linux.vnet.ibm.com> Remove html tags from i18n as they are not valid Correct object definition from acceptable JS to valid JSON replacing ' with " in attribute names. Update root.py to make Cheetah render the JSON template. Signed-off-by: Adam King <rak@linux.vnet.ibm.com> Signed-off-by: ShaoHe Feng <shaohef@linux.vnet.ibm.com> --- ui/pages/i18n.html.tmpl | 178 ------------------------------------------------ ui/pages/i18n.json.tmpl | 165 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 165 insertions(+), 178 deletions(-) delete mode 100644 ui/pages/i18n.html.tmpl create mode 100644 ui/pages/i18n.json.tmpl diff --git a/ui/pages/i18n.html.tmpl b/ui/pages/i18n.html.tmpl deleted file mode 100644 index 25b81c2..0000000 --- a/ui/pages/i18n.html.tmpl +++ /dev/null @@ -1,178 +0,0 @@ -#* - * Project Kimchi - * - * Copyright IBM, Corp. 2013 - * - * 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. - *# -#unicode UTF-8 -#import gettext -#from kimchi.cachebust import href -#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang) -#silent _ = t.gettext -#silent _t = t.gettext - -<!DOCTYPE html> -<html class="no-js" lang=$lang.lang[0]> -<head> - <meta charset="utf-8"> - <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> - <title>language</title> -</head> -<body> -<script> -var i18n = { - 'KCHAUTH6001E': "$_("The username or password you entered is incorrect. Please try again.")", - 'KCHAUTH6002E': "$_("This field is required.")", - - 'KCHAUTH6001M': "$_("Log in")", - 'KCHAUTH6002M': "$_("Logging in...")", - - 'Host': "$_("Host")", - 'Guests': "$_("Guests")", - 'Templates': "$_("Templates")", - 'Storage': "$_("Storage")", - 'Network': "$_("Network")", - - 'KCHAPI6001E': "$_("Invalid URL. Redireced to home page.")", - 'KCHAPI6002E': "$_("Failed to get application configuration")", - 'KCHAPI6003E': "$_("This is not a valid Linux path")", - 'KCHAPI6004E': "$_("This is not a valid URL.")", - 'KCHAPI6005E': "$_("No such data available.")", - 'KCHAPI6006E': "$_("options needed.")", - 'KCHAPI6007E': "$_("Can not contact the host system. Verify the host system is up and that you have network connectivity to it. HTTP request response %1. ")", - - 'KCHAPI6001M': "$_("Delete Confirmation")", - 'KCHAPI6002M': "$_("OK")", - 'KCHAPI6003M': "$_("Cancel")", - 'KCHAPI6004M': "$_("Confirm")", - 'KCHAPI6005M': "$_("Create")", - 'KCHAPI6006M': "$_("Warning")", - 'KCHAPI6007M': "$_("Save")", - - 'KCHGRD6001M': "$_("Loading...")", - 'KCHGRD6002M': "$_("An error occurs while checking for packages update.")", - 'KCHGRD6003M': "$_("Retry")", - 'KCHGRD6004M': "$_("Detailed message:")", - - 'KCHTMPL6001W': "$_("No iso found")", - - 'KCHTMPL6002E': "$_("This is not a valid ISO file.")", - - 'KCHTMPL6002M': "$_("It will take long time. Do you want to continue?")", - 'KCHTMPL6003M': "$_("This will permanently delete the template. Would you like to continue?")", - - 'KCHHOST6001E': "$_("Unable to shut down system as there are some virtual machines running!")", - - 'KCHHOST6001M': "$_("Max:")", - 'KCHHOST6002M': "$_("Utilization")", - 'KCHHOST6003M': "$_("Available")", - 'KCHHOST6004M': "$_("Read Rate")", - 'KCHHOST6005M': "$_("Write Rate")", - 'KCHHOST6006M': "$_("Received")", - 'KCHHOST6007M': "$_("Sent")", - 'KCHHOST6008M': "$_("Shutting down or restarting host will cause unsaved work lost. Continue to shut down/restarting?")", - - - 'KCHREPO6001M': "$_("Confirm")", - 'KCHREPO6002M': "$_("Repository will be removed permanently and can't be recovered. Do you want to continue?")", - 'KCHREPO6003M': "$_("Repositories")", - 'KCHREPO6004M': "$_("ID")", - 'KCHREPO6005M': "$_("Name")", - 'KCHREPO6006M': "$_("Base URL")", - 'KCHREPO6007M': "$_("Is Mirror")", - 'KCHREPO6008M': "$_("URL Args")", - 'KCHREPO6009M': "$_("Enabled")", - 'KCHREPO6010M': "$_("GPG Check")", - 'KCHREPO6011M': "$_("GPG Key")", - 'KCHREPO6012M': "$_("Add")", - 'KCHREPO6013M': "$_("Edit")", - 'KCHREPO6014M': "$_("Remove")", - 'KCHREPO6015M': "$_("Failed.")", - 'KCHREPO6016M': "$_("Enable")", - 'KCHREPO6017M': "$_("Disable")", - - - 'KCHUPD6001M': "$_("Software Updates")", - 'KCHUPD6002M': "$_("Package Name")", - 'KCHUPD6003M': "$_("Version")", - 'KCHUPD6004M': "$_("Architecture")", - 'KCHUPD6005M': "$_("Repository")", - 'KCHUPD6006M': "$_("Update All")", - 'KCHUPD6007M': "$_("Updating...")", - 'KCHUPD6008M': "$_("Failed to retrieve updates.")", - 'KCHUPD6009M': "$_("Failed to update package(s).")", - - - 'KCHDR6001M': "$_("Debug report will be removed permanently and can't be recovered. Do you want to continue?")", - 'KCHDR6002M': "$_("Debug Reports")", - 'KCHDR6003M': "$_("Name")", - 'KCHDR6005M': "$_("Generated Time")", - 'KCHDR6006M': "$_("Generate")", - 'KCHDR6007M': "$_("Generating...")", - 'KCHDR6008M': "$_("Rename")", - 'KCHDR6009M': "$_("Remove")", - 'KCHDR6010M': "$_("Download")", - 'KCHDR6011M': "$_("Report name should contain only letters, digits and/or hyphen ('-').")", - - 'KCHVM6001M': "$_("This will delete the virtual machine and its virtual disks. This operation cannot be undone. Would you like to continue?")", - 'KCHVM6002M': "$_("Power off Confirmation")", - 'KCHVM6003M': "$_("This action may produce undesirable results, " - "for example unflushed disk cache in the guest. " - "Would you like to continue?")", - 'KCHVM6004M': "$_("Reset Confirmation")", - 'KCHVM6005M': "$_("There is a risk of data loss caused by reset without" - " the guest OS shutdown. Would you like to continue?")", - 'KCHVM6006M': "$_("Shut Down Confirmation")", - 'KCHVM6007M': "$_("Note the guest OS may ignore this request. Would you like to continue?")", - 'KCHVM6008M': "$_("VM Delete Confirmation")", - - 'KCHVMCD6001M': "$_("This CDROM will be detached permanently and you can re-attach it. Continue to detach it?")", - 'KCHVMCD6002M': "$_("Attach")", - 'KCHVMCD6003M': "$_("Attaching...")", - 'KCHVMCD6004M': "$_("Replace")", - 'KCHVMCD6005M': "$_("Replacing...")", - 'KCHVMCD6006M': "$_("Successfully attached!")", - 'KCHVMCD6007M': "$_("Successfully replaced!")", - 'KCHVMCD6008M': "$_("Successfully detached!")", - - - 'KCHNET6001E': "$_("The VLAN id must be between 1 and 4094.")", - - 'KCHNET6001M': "$_("unavailable")", - 'KCHNET6002M': "$_("This action will interrupt network connectivity for any virtual machine that depend on this network.")", - 'KCHNET6003M': "$_("Create a network")", - 'KCHNET6004M': "$_("This network is not persistent. Instead of stop, this action will permanently delete it. Would you like to continue?")", - - 'KCHPOOL6001M': "$_("This will permanently delete the storage pool. Would you like to continue?")", - 'KCHPOOL6002M': "$_("This storage pool is empty.")", - 'KCHPOOL6003M': "$_("It will format your disk and you will loose any data in there, are you sure to continue? ")", - 'KCHPOOL6004M': "$_("SCSI Fibre Channel")", - 'KCHPOOL6005M': "$_("No SCSI adapters found.")", - - 'KCHPOOL6001E': "$_("The storage pool name can not be blank.")", - 'KCHPOOL6002E': "$_("The storage pool path can not be blank.")", - 'KCHPOOL6003E': "$_("NFS server mount path can not be blank.")", - 'KCHPOOL6004E': "$_("Invalid storage pool name. It should not contain '/'.")", - 'KCHPOOL6005E': "$_("Invalid NFS mount path.")", - 'KCHPOOL6006E': "$_("No logical device selected.")", - 'KCHPOOL6007E': "$_("The iSCSI target can not be blank.")", - 'KCHPOOL6008E': "$_("Server name can not be blank.")", - 'KCHPOOL6009E': "$_("This is not a valid Server Name or IP. please, modify it.")", - 'KCHPOOL6010M': "$_("Looking for available partitions ...")", - 'KCHPOOL6011M': "$_("No available partitions found.")", - 'KCHPOOL6012M': "$_("This storage pool is not persistent. Instead of deactivate, this action will permanently delete it. Would you like to continue?")" -}; -</script> -</body> -</html> diff --git a/ui/pages/i18n.json.tmpl b/ui/pages/i18n.json.tmpl new file mode 100644 index 0000000..3ef488f --- /dev/null +++ b/ui/pages/i18n.json.tmpl @@ -0,0 +1,165 @@ +#* + * Project Kimchi + * + * Copyright IBM, Corp. 2013 + * + * 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. + *# +#unicode UTF-8 +#import gettext +#from kimchi.cachebust import href +#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang) +#silent _ = t.gettext +#silent _t = t.gettext +{ + "KCHAUTH6001E": "$_("The username or password you entered is incorrect. Please try again.")", + "KCHAUTH6002E": "$_("This field is required.")", + + "KCHAUTH6001M": "$_("Log in")", + "KCHAUTH6002M": "$_("Logging in...")", + + "Host": "$_("Host")", + "Guests": "$_("Guests")", + "Templates": "$_("Templates")", + "Storage": "$_("Storage")", + "Network": "$_("Network")", + + "KCHAPI6001E": "$_("Invalid URL. Redireced to home page.")", + "KCHAPI6002E": "$_("Failed to get application configuration")", + "KCHAPI6003E": "$_("This is not a valid Linux path")", + "KCHAPI6004E": "$_("This is not a valid URL.")", + "KCHAPI6005E": "$_("No such data available.")", + "KCHAPI6006E": "$_("options needed.")", + "KCHAPI6007E": "$_("Can not contact the host system. Verify the host system is up and that you have network connectivity to it. HTTP request response %1. ")", + + "KCHAPI6001M": "$_("Delete Confirmation")", + "KCHAPI6002M": "$_("OK")", + "KCHAPI6003M": "$_("Cancel")", + "KCHAPI6004M": "$_("Confirm")", + "KCHAPI6005M": "$_("Create")", + "KCHAPI6006M": "$_("Warning")", + "KCHAPI6007M": "$_("Save")", + + "KCHGRD6001M": "$_("Loading...")", + "KCHGRD6002M": "$_("An error occurs while checking for packages update.")", + "KCHGRD6003M": "$_("Retry")", + "KCHGRD6004M": "$_("Detailed message:")", + + "KCHTMPL6001W": "$_("No iso found")", + + "KCHTMPL6002E": "$_("This is not a valid ISO file.")", + + "KCHTMPL6002M": "$_("It will take long time. Do you want to continue?")", + "KCHTMPL6003M": "$_("This will permanently delete the template. Would you like to continue?")", + + "KCHHOST6001E": "$_("Unable to shut down system as there are some virtual machines running!")", + + "KCHHOST6001M": "$_("Max:")", + "KCHHOST6002M": "$_("Utilization")", + "KCHHOST6003M": "$_("Available")", + "KCHHOST6004M": "$_("Read Rate")", + "KCHHOST6005M": "$_("Write Rate")", + "KCHHOST6006M": "$_("Received")", + "KCHHOST6007M": "$_("Sent")", + "KCHHOST6008M": "$_("Shutting down or restarting host will cause unsaved work lost. Continue to shut down/restarting?")", + + + "KCHREPO6001M": "$_("Confirm")", + "KCHREPO6002M": "$_("Repository will be removed permanently and can't be recovered. Do you want to continue?")", + "KCHREPO6003M": "$_("Repositories")", + "KCHREPO6004M": "$_("ID")", + "KCHREPO6005M": "$_("Name")", + "KCHREPO6006M": "$_("Base URL")", + "KCHREPO6007M": "$_("Is Mirror")", + "KCHREPO6008M": "$_("URL Args")", + "KCHREPO6009M": "$_("Enabled")", + "KCHREPO6010M": "$_("GPG Check")", + "KCHREPO6011M": "$_("GPG Key")", + "KCHREPO6012M": "$_("Add")", + "KCHREPO6013M": "$_("Edit")", + "KCHREPO6014M": "$_("Remove")", + "KCHREPO6015M": "$_("Failed.")", + "KCHREPO6016M": "$_("Enable")", + "KCHREPO6017M": "$_("Disable")", + + + "KCHUPD6001M": "$_("Software Updates")", + "KCHUPD6002M": "$_("Package Name")", + "KCHUPD6003M": "$_("Version")", + "KCHUPD6004M": "$_("Architecture")", + "KCHUPD6005M": "$_("Repository")", + "KCHUPD6006M": "$_("Update All")", + "KCHUPD6007M": "$_("Updating...")", + "KCHUPD6008M": "$_("Failed to retrieve updates.")", + "KCHUPD6009M": "$_("Failed to update package(s).")", + + + "KCHDR6001M": "$_("Debug report will be removed permanently and can't be recovered. Do you want to continue?")", + "KCHDR6002M": "$_("Debug Reports")", + "KCHDR6003M": "$_("Name")", + "KCHDR6005M": "$_("Generated Time")", + "KCHDR6006M": "$_("Generate")", + "KCHDR6007M": "$_("Generating...")", + "KCHDR6008M": "$_("Rename")", + "KCHDR6009M": "$_("Remove")", + "KCHDR6010M": "$_("Download")", + "KCHDR6011M": "$_("Report name should contain only letters, digits and/or hyphen ('-').")", + + "KCHVM6001M": "$_("This will delete the virtual machine and its virtual disks. This operation cannot be undone. Would you like to continue?")", + "KCHVM6002M": "$_("Power off Confirmation")", + "KCHVM6003M": "$_("This action may produce undesirable results, " + "for example unflushed disk cache in the guest. " + "Would you like to continue?")", + "KCHVM6004M": "$_("Reset Confirmation")", + "KCHVM6005M": "$_("There is a risk of data loss caused by reset without" + " the guest OS shutdown. Would you like to continue?")", + "KCHVM6006M": "$_("Shut Down Confirmation")", + "KCHVM6007M": "$_("Note the guest OS may ignore this request. Would you like to continue?")", + "KCHVM6008M": "$_("VM Delete Confirmation")", + + "KCHVMCD6001M": "$_("This CDROM will be detached permanently and you can re-attach it. Continue to detach it?")", + "KCHVMCD6002M": "$_("Attach")", + "KCHVMCD6003M": "$_("Attaching...")", + "KCHVMCD6004M": "$_("Replace")", + "KCHVMCD6005M": "$_("Replacing...")", + "KCHVMCD6006M": "$_("Successfully attached!")", + "KCHVMCD6007M": "$_("Successfully replaced!")", + "KCHVMCD6008M": "$_("Successfully detached!")", + + + "KCHNET6001E": "$_("The VLAN id must be between 1 and 4094.")", + + "KCHNET6001M": "$_("unavailable")", + "KCHNET6002M": "$_("This action will interrupt network connectivity for any virtual machine that depend on this network.")", + "KCHNET6003M": "$_("Create a network")", + "KCHNET6004M": "$_("This network is not persistent. Instead of stop, this action will permanently delete it. Would you like to continue?")", + + "KCHPOOL6001M": "$_("This will permanently delete the storage pool. Would you like to continue?")", + "KCHPOOL6002M": "$_("This storage pool is empty.")", + "KCHPOOL6003M": "$_("It will format your disk and you will loose any data in there, are you sure to continue? ")", + "KCHPOOL6004M": "$_("SCSI Fibre Channel")", + "KCHPOOL6005M": "$_("No SCSI adapters found.")", + + "KCHPOOL6001E": "$_("The storage pool name can not be blank.")", + "KCHPOOL6002E": "$_("The storage pool path can not be blank.")", + "KCHPOOL6003E": "$_("NFS server mount path can not be blank.")", + "KCHPOOL6004E": "$_("Invalid storage pool name. It should not contain '/'.")", + "KCHPOOL6005E": "$_("Invalid NFS mount path.")", + "KCHPOOL6006E": "$_("No logical device selected.")", + "KCHPOOL6007E": "$_("The iSCSI target can not be blank.")", + "KCHPOOL6008E": "$_("Server name can not be blank.")", + "KCHPOOL6009E": "$_("This is not a valid Server Name or IP. please, modify it.")", + "KCHPOOL6010M": "$_("Looking for available partitions ...")", + "KCHPOOL6011M": "$_("No available partitions found.")", + "KCHPOOL6012M": "$_("This storage pool is not persistent. Instead of deactivate, this action will permanently delete it. Would you like to continue?")" +} \ No newline at end of file -- 1.9.3

From: ShaoHe Feng <shaohef@linux.vnet.ibm.com> Create an API for fetching the i18n JSON. Use the API to load the kimchi UI strings. API will need to be simplified after convincing CherryPy to respond to the reque st for JSON. Signed-off-by: Adam King <rak@linux.vnet.ibm.com> Signed-off-by: ShaoHe Feng <shaohef@linux.vnet.ibm.com> --- ui/js/src/kimchi.api.js | 14 ++++++++++++++ ui/js/src/kimchi.main.js | 11 ++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js index 072d127..ad89880 100644 --- a/ui/js/src/kimchi.api.js +++ b/ui/js/src/kimchi.api.js @@ -63,6 +63,20 @@ var kimchi = { }, /** + * Get the i18 strings. + */ + getI18n: function(suc, err, url, sync) { + kimchi.requestJSON({ + url : url ? url : kimchi.url + 'i18n.json', + type : 'GET', + resend: true, + dataType : 'json', + success : suc, + error: err + }); + }, + + /** * Get the host static information. */ getHost: function(suc, err) { diff --git a/ui/js/src/kimchi.main.js b/ui/js/src/kimchi.main.js index 184029d..1e6602c 100644 --- a/ui/js/src/kimchi.main.js +++ b/ui/js/src/kimchi.main.js @@ -247,9 +247,14 @@ kimchi.main = function() { }; // Load i18n translation strings first and then render the page. - $('#main').load('i18n.html', function() { - buildTabs(initUI); - }); + kimchi.getI18n( + function(i18nStrings){ //success + i18n = i18nStrings; + buildTabs(initUI); + }, + function(data){ //error + kimchi.message.error(data.responseJSON.reason); + }); }; kimchi.getHelp = function(e) { -- 1.9.3

From: ShaoHe Feng <shaohef@linux.vnet.ibm.com> Apparently, in plugin code there is no way to insert new entries into Kimchi ./ui/pages/i18n.json.tmpl, so every plugin should provide its own i18n.json.tmpl. each plugin provides a "plugins/plugin-name/ui/pages/i18n.json.tmpl", and maps it to the URI "plugins/plugin-name/json.html". This is already supported by the kimchi back-end. What we have to do is just to load "plugins/plugin-name/i18n.json" in the front-end code. Signed-off-by: Adam King <rak@linux.vnet.ibm.com> Signed-off-by: ShaoHe Feng <shaohef@linux.vnet.ibm.com> --- ui/js/src/kimchi.api.js | 4 +++- ui/js/src/kimchi.main.js | 13 +++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js index ad89880..0d96d07 100644 --- a/ui/js/src/kimchi.api.js +++ b/ui/js/src/kimchi.api.js @@ -71,6 +71,7 @@ var kimchi = { type : 'GET', resend: true, dataType : 'json', + async : !sync, success : suc, error: err }); @@ -560,13 +561,14 @@ var kimchi = { }); }, - listPlugins : function(suc, err) { + listPlugins : function(suc, err, sync) { kimchi.requestJSON({ url : kimchi.url + 'plugins', type : 'GET', contentType : 'application/json', dataType : 'json', resend: true, + async : !sync, success : suc, error : err }); diff --git a/ui/js/src/kimchi.main.js b/ui/js/src/kimchi.main.js index 1e6602c..eb4575a 100644 --- a/ui/js/src/kimchi.main.js +++ b/ui/js/src/kimchi.main.js @@ -39,7 +39,7 @@ kimchi.main = function() { $(xmlData).find('tab').each(function() { var $tab = $(this); var titleKey = $tab.find('title').text(); - var title = i18n[titleKey]; + var title = i18n[titleKey] ? i18n[titleKey] : titleKey; var path = $tab.find('path').text(); tabs.push({ title: title, @@ -64,6 +64,7 @@ kimchi.main = function() { var tabConfigUrl = '/config/ui/tabs.xml'; var pluginConfigUrl = '/plugins/{plugin}/ui/config/tab-ext.xml'; + var pluginI18nUrl = 'plugins/{plugin}/i18n.json'; var DEFAULT_HASH; var buildTabs = function(callback) { var tabs = retrieveTabs(tabConfigUrl); @@ -72,6 +73,12 @@ kimchi.main = function() { var url = kimchi.substitute(pluginConfigUrl, { plugin: p }); + var i18nUrl = kimchi.substitute(pluginI18nUrl, { + plugin: p + }); + kimchi.getI18n(function(i18nObj){ $.extend(i18n, i18nObj)}, + function(i18nObj){ //i18n is not define by plugin + }, i18nUrl, true); tabs.push.apply(tabs, retrieveTabs(url)); }); @@ -85,7 +92,9 @@ kimchi.main = function() { $('#nav-menu').append(genTabs(tabs)); callback && callback(); - }); + }, function(data) { + kimchi.message.error(data.responseJSON.reason); + }, true); }; var onLanguageChanged = function(lang) { -- 1.9.3

From: ShaoHe Feng <shaohef@linux.vnet.ibm.com> sample plugin is used to test as a plugin demo. we disable it by default. use this command to enable sample plugin $ ./autogen.sh --enable-plugins Signed-off-by: ShaoHe Feng <shaohef@linux.vnet.ibm.com> --- configure.ac | 10 ++++++++++ plugins/sample/Makefile.am | 17 ++++++++++++++++- plugins/sample/{sample.conf => sample.conf.in} | 2 +- 3 files changed, 27 insertions(+), 2 deletions(-) rename plugins/sample/{sample.conf => sample.conf.in} (91%) diff --git a/configure.ac b/configure.ac index cc971e8..047cf9d 100644 --- a/configure.ac +++ b/configure.ac @@ -48,6 +48,16 @@ if test "x$PYFLAKES" = "x"; then AC_MSG_WARN([pyflakes not found]) fi +AC_ARG_ENABLE( + [sample], + [AS_HELP_STRING( + [--enable-sample], + [build sample plugin package @<:@default=no@:>@] + )], + , + [enable_sample="no"] +) +AM_CONDITIONAL([SAMPLE], [test "${enable_sample}" = "yes"]) AC_CONFIG_FILES([ po/Makefile.in diff --git a/plugins/sample/Makefile.am b/plugins/sample/Makefile.am index e03a4c0..7835c3f 100644 --- a/plugins/sample/Makefile.am +++ b/plugins/sample/Makefile.am @@ -19,4 +19,19 @@ SUBDIRS = ui -EXTRA_DIST = API.json sample.conf $(wildcard *.py) +EXTRA_DIST = API.json sample.conf.in $(wildcard *.py) + +if SAMPLE +ENABLE_SAMPLE = True +else +ENABLE_SAMPLE = False +endif + +do_substitution = \ + sed -e 's,[@]ENABLE_SAMPLE[@],$(ENABLE_SAMPLE),g' + +sample.conf: sample.conf.in Makefile + $(do_substitution) < $< > $@ + +BUILT_SOURCES = sample.conf +CLEANFILES = sample.conf diff --git a/plugins/sample/sample.conf b/plugins/sample/sample.conf.in similarity index 91% rename from plugins/sample/sample.conf rename to plugins/sample/sample.conf.in index 78a9f4e..f890983 100644 --- a/plugins/sample/sample.conf +++ b/plugins/sample/sample.conf.in @@ -1,5 +1,5 @@ [kimchi] -enable = True +enable = @ENABLE_SAMPLE@ plugin_class = "Drawings" uri = "/plugins/sample" -- 1.9.3

on 2014/06/09 16:02, shaohef@linux.vnet.ibm.com wrote:
From: ShaoHe Feng <shaohef@linux.vnet.ibm.com>
sample plugin is used to test as a plugin demo.
we disable it by default.
use this command to enable sample plugin $ ./autogen.sh --enable-plugins
Signed-off-by: ShaoHe Feng <shaohef@linux.vnet.ibm.com> --- configure.ac | 10 ++++++++++ plugins/sample/Makefile.am | 17 ++++++++++++++++- plugins/sample/{sample.conf => sample.conf.in} | 2 +- 3 files changed, 27 insertions(+), 2 deletions(-) rename plugins/sample/{sample.conf => sample.conf.in} (91%)
diff --git a/configure.ac b/configure.ac index cc971e8..047cf9d 100644 --- a/configure.ac +++ b/configure.ac @@ -48,6 +48,16 @@ if test "x$PYFLAKES" = "x"; then AC_MSG_WARN([pyflakes not found]) fi
+AC_ARG_ENABLE( + [sample], + [AS_HELP_STRING( + [--enable-sample], + [build sample plugin package @<:@default=no@:>@] + )], + , + [enable_sample="no"] +) +AM_CONDITIONAL([SAMPLE], [test "${enable_sample}" = "yes"])
AC_CONFIG_FILES([ po/Makefile.in diff --git a/plugins/sample/Makefile.am b/plugins/sample/Makefile.am index e03a4c0..7835c3f 100644 --- a/plugins/sample/Makefile.am +++ b/plugins/sample/Makefile.am @@ -19,4 +19,19 @@
SUBDIRS = ui
-EXTRA_DIST = API.json sample.conf $(wildcard *.py) +EXTRA_DIST = API.json sample.conf.in $(wildcard *.py) + +if SAMPLE +ENABLE_SAMPLE = True +else +ENABLE_SAMPLE = False +endif + +do_substitution = \ + sed -e 's,[@]ENABLE_SAMPLE[@],$(ENABLE_SAMPLE),g'
This is a little too magical. If it's possible, I suggest adding sample.conf.in into configure.ac substitution list.
+ +sample.conf: sample.conf.in Makefile + $(do_substitution) < $< > $@ + +BUILT_SOURCES = sample.conf +CLEANFILES = sample.conf diff --git a/plugins/sample/sample.conf b/plugins/sample/sample.conf.in similarity index 91% rename from plugins/sample/sample.conf rename to plugins/sample/sample.conf.in index 78a9f4e..f890983 100644 --- a/plugins/sample/sample.conf +++ b/plugins/sample/sample.conf.in @@ -1,5 +1,5 @@ [kimchi] -enable = True +enable = @ENABLE_SAMPLE@ plugin_class = "Drawings" uri = "/plugins/sample"
-- Zhou Zheng Sheng / 周征晟 E-mail: zhshzhou@linux.vnet.ibm.com Telephone: 86-10-82454397

From: ShaoHe Feng <shaohef@linux.vnet.ibm.com> please use this command to generate the translation files for plugins/sample $ make -C plugins/sample/po/ update-po Signed-off-by: ShaoHe Feng <shaohef@linux.vnet.ibm.com> --- configure.ac | 1 + plugins/sample/Makefile.am | 9 ++++++++- plugins/sample/config.status | 1 + plugins/sample/po/LINGUAS | 1 + plugins/sample/po/Makefile.in.in | 1 + plugins/sample/po/Makevars | 1 + plugins/sample/po/POTFILES.in | 2 ++ plugins/sample/po/en_US.po | 21 +++++++++++++++++++++ plugins/sample/po/gen-pot | 1 + plugins/sample/po/pt_BR.po | 24 ++++++++++++++++++++++++ plugins/sample/po/zh_CN.po | 24 ++++++++++++++++++++++++ 11 files changed, 85 insertions(+), 1 deletion(-) create mode 120000 plugins/sample/config.status create mode 120000 plugins/sample/po/LINGUAS create mode 120000 plugins/sample/po/Makefile.in.in create mode 120000 plugins/sample/po/Makevars create mode 100644 plugins/sample/po/POTFILES.in create mode 100644 plugins/sample/po/en_US.po create mode 120000 plugins/sample/po/gen-pot create mode 100644 plugins/sample/po/pt_BR.po create mode 100644 plugins/sample/po/zh_CN.po diff --git a/configure.ac b/configure.ac index 047cf9d..13dd967 100644 --- a/configure.ac +++ b/configure.ac @@ -72,6 +72,7 @@ AC_CONFIG_FILES([ src/kimchi/model/Makefile plugins/Makefile plugins/sample/Makefile + plugins/sample/po/Makefile.in plugins/sample/ui/Makefile plugins/sample/ui/config/Makefile ui/Makefile diff --git a/plugins/sample/Makefile.am b/plugins/sample/Makefile.am index 7835c3f..0bc601b 100644 --- a/plugins/sample/Makefile.am +++ b/plugins/sample/Makefile.am @@ -17,7 +17,7 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -SUBDIRS = ui +SUBDIRS = ui po EXTRA_DIST = API.json sample.conf.in $(wildcard *.py) @@ -35,3 +35,10 @@ sample.conf: sample.conf.in Makefile BUILT_SOURCES = sample.conf CLEANFILES = sample.conf + +all-local: + while read L && test -n "$$L"; do \ + dir=mo/$$L/LC_MESSAGES ; \ + $(MKDIR_P) $$dir ; \ + ln -sf ../../../po/$$L.gmo $$dir/kimchi.mo ; \ + done < po/LINGUAS diff --git a/plugins/sample/config.status b/plugins/sample/config.status new file mode 120000 index 0000000..6cd6b4f --- /dev/null +++ b/plugins/sample/config.status @@ -0,0 +1 @@ +../../config.status \ No newline at end of file diff --git a/plugins/sample/po/LINGUAS b/plugins/sample/po/LINGUAS new file mode 120000 index 0000000..4fb83a5 --- /dev/null +++ b/plugins/sample/po/LINGUAS @@ -0,0 +1 @@ +../../../po/LINGUAS \ No newline at end of file diff --git a/plugins/sample/po/Makefile.in.in b/plugins/sample/po/Makefile.in.in new file mode 120000 index 0000000..44028c0 --- /dev/null +++ b/plugins/sample/po/Makefile.in.in @@ -0,0 +1 @@ +../../../po/Makefile.in.in \ No newline at end of file diff --git a/plugins/sample/po/Makevars b/plugins/sample/po/Makevars new file mode 120000 index 0000000..3b6b02f --- /dev/null +++ b/plugins/sample/po/Makevars @@ -0,0 +1 @@ +../../../po/Makevars \ No newline at end of file diff --git a/plugins/sample/po/POTFILES.in b/plugins/sample/po/POTFILES.in new file mode 100644 index 0000000..f1b069f --- /dev/null +++ b/plugins/sample/po/POTFILES.in @@ -0,0 +1,2 @@ +# List of source files which contain translatable strings. +ui/pages/*.tmpl diff --git a/plugins/sample/po/en_US.po b/plugins/sample/po/en_US.po new file mode 100644 index 0000000..1889845 --- /dev/null +++ b/plugins/sample/po/en_US.po @@ -0,0 +1,21 @@ +# English translations for kimchi package. +# Copyright (C) 2014 THE kimchi'S COPYRIGHT HOLDER +# This file is distributed under the same license as the kimchi package. +# shhfeng <shaohef@linux.vnet.ibm.com>, 2014. +# +msgid "" +msgstr "" +"Project-Id-Version: kimchi 1.2.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-05-17 02:13+0800\n" +"PO-Revision-Date: 2014-05-17 02:08+0800\n" +"Last-Translator: shhfeng <shaohef@linux.vnet.ibm.com>\n" +"Language-Team: English\n" +"Language: en_US\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=ASCII\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: pygettext.py 1.5\n" + +msgid "SampleTab" +msgstr "SampleTab" diff --git a/plugins/sample/po/gen-pot b/plugins/sample/po/gen-pot new file mode 120000 index 0000000..b449d56 --- /dev/null +++ b/plugins/sample/po/gen-pot @@ -0,0 +1 @@ +../../../po/gen-pot \ No newline at end of file diff --git a/plugins/sample/po/pt_BR.po b/plugins/sample/po/pt_BR.po new file mode 100644 index 0000000..0ff1d43 --- /dev/null +++ b/plugins/sample/po/pt_BR.po @@ -0,0 +1,24 @@ +# Portuguese translations for kimchi package +# Copyright (C) 2014 THE kimchi'S COPYRIGHT HOLDER +# This file is distributed under the same license as the kimchi package. +# shhfeng <shaohef@linux.vnet.ibm.com>, 2014. +# +msgid "" +msgstr "" +"Project-Id-Version: kimchi 1.2.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-05-17 02:13+0800\n" +"PO-Revision-Date: 2014-05-17 02:09+0800\n" +"Last-Translator: Crístian Viana <vianac@linux.vnet.ibm.com>\n" +"Language-Team: Aline Manera <alinefm@br.ibm.com>\n" +"Language: pt_BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: pygettext.py 1.5\n" +"X-Poedit-Country: Brazil\n" +"X-Poedit-Language: Portuguese\n" +"X-Poedit-SourceCharset: utf-8\n" + +msgid "SampleTab" +msgstr "Tab de exemplo" diff --git a/plugins/sample/po/zh_CN.po b/plugins/sample/po/zh_CN.po new file mode 100644 index 0000000..bba53c3 --- /dev/null +++ b/plugins/sample/po/zh_CN.po @@ -0,0 +1,24 @@ +# Chinese translations for kimchi package +# Copyright (C) 2014 THE kimchi'S COPYRIGHT HOLDER +# This file is distributed under the same license as the kimchi package. +# shhfeng <shaohef@linux.vnet.ibm.com>, 2014. +# +msgid "" +msgstr "" +"Project-Id-Version: kimchi 1.2.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-05-17 02:13+0800\n" +"PO-Revision-Date: 2014-05-17 02:10+0800\n" +"Last-Translator: shhfeng <shaohef@linux.vnet.ibm.com>\n" +"Language-Team: Chinese (simplified)\n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: pygettext.py 1.5\n" +"X-Poedit-Country: CHINA\n" +"X-Poedit-Language: Chinese\n" +"X-Poedit-SourceCharset: utf-8\n" + +msgid "SampleTab" +msgstr "示例标签" -- 1.9.3
participants (2)
-
shaohef@linux.vnet.ibm.com
-
Zhou Zheng Sheng