控制节点
sudo -i
#进入horizon服务的容器
lxc-attach -n infra1_horizon_container-314417a3
#在用户根目录创建目录zunui-i18n
mkdir ~/zunui-i18n
# 进入目录
cd ~/zunui-i18n
#将要替换的文件发送到这个目录下
rz
# 备份
cp /openstack/venvs/horizon-18.1.5/lib/python2.7/site-packages/openstack_dashboard/locale/zh_CN/LC_MESSAGES/django.po /openstack/venvs/horizon-18.1.5/lib/python2.7/site-packages/openstack_dashboard/locale/zh_CN/LC_MESSAGES/django.po.bak
cp /openstack/venvs/horizon-18.1.5/lib/python2.7/site-packages/openstack_dashboard/locale/zh_CN/LC_MESSAGES/djangojs.po /openstack/venvs/horizon-18.1.5/lib/python2.7/site-packages/openstack_dashboard/locale/zh_CN/LC_MESSAGES/djangojs.po.bak
cp /openstack/venvs/horizon-18.1.5/lib/python2.7/site-packages/zun_ui/static/dashboard/container/containers/details/console.controller.js /openstack/venvs/horizon-18.1.5/lib/python2.7/site-packages/zun_ui/static/dashboard/container/containers/details/console.controller.js.bak
cp /openstack/venvs/horizon-18.1.5/lib/python2.7/site-packages/zun_ui/static/cloud-shell/cloud-shell.controller.js /openstack/venvs/horizon-18.1.5/lib/python2.7/site-packages/zun_ui/static/cloud-shell/cloud-shell.controller.js.bak
# 拷贝文件并修改权限和所有者
cp ~/zunui-i18n/django.po /openstack/venvs/horizon-18.1.5/lib/python2.7/site-packages/openstack_dashboard/locale/zh_CN/LC_MESSAGES/
chown root:root /openstack/venvs/horizon-18.1.5/lib/python2.7/site-packages/openstack_dashboard/locale/zh_CN/LC_MESSAGES/django.po
chmod 644 /openstack/venvs/horizon-18.1.5/lib/python2.7/site-packages/openstack_dashboard/locale/zh_CN/LC_MESSAGES/django.po
cp ~/zunui-i18n/djangojs.po /openstack/venvs/horizon-18.1.5/lib/python2.7/site-packages/openstack_dashboard/locale/zh_CN/LC_MESSAGES/
chown root:root /openstack/venvs/horizon-18.1.5/lib/python2.7/site-packages/openstack_dashboard/locale/zh_CN/LC_MESSAGES/djangojs.po
chmod 644 /openstack/venvs/horizon-18.1.5/lib/python2.7/site-packages/openstack_dashboard/locale/zh_CN/LC_MESSAGES/djangojs.po
cp ~/zunui-i18n/console.controller.js /openstack/venvs/horizon-18.1.5/lib/python2.7/site-packages/zun_ui/static/dashboard/container/containers/details/
chown root:root /openstack/venvs/horizon-18.1.5/lib/python2.7/site-packages/zun_ui/static/dashboard/container/containers/details/console.controller.js
chmod 644 /openstack/venvs/horizon-18.1.5/lib/python2.7/site-packages/zun_ui/static/dashboard/container/containers/details/console.controller.js
cp ~/zunui-i18n/cloud-shell.controller.js /openstack/venvs/horizon-18.1.5/lib/python2.7/site-packages/zun_ui/static/cloud-shell/
chown root:root /openstack/venvs/horizon-18.1.5/lib/python2.7/site-packages/zun_ui/static/cloud-shell/cloud-shell.controller.js
chmod 644 /openstack/venvs/horizon-18.1.5/lib/python2.7/site-packages/zun_ui/static/cloud-shell/cloud-shell.controller.js
# 翻译po
msgfmt --statistics --verbose -o /openstack/venvs/horizon-18.1.5/lib/python2.7/site-packages/openstack_dashboard/locale/zh_CN/LC_MESSAGES/django.mo /openstack/venvs/horizon-18.1.5/lib/python2.7/site-packages/openstack_dashboard/locale/zh_CN/LC_MESSAGES/django.po
msgfmt --statistics --verbose -o /openstack/venvs/horizon-18.1.5/lib/python2.7/site-packages/openstack_dashboard/locale/zh_CN/LC_MESSAGES/djangojs.mo /openstack/venvs/horizon-18.1.5/lib/python2.7/site-packages/openstack_dashboard/locale/zh_CN/LC_MESSAGES/djangojs.po
# 发布静态文件
/openstack/venvs/horizon-18.1.5/bin/horizon-manage.py collectstatic --noinput
/openstack/venvs/horizon-18.1.5/bin/horizon-manage.py compress --force
# 重启并查看Apache服务
systemctl restart apache2
systemctl status apache2
(以上脚本被保存在文件i18n-zunui.sh中。)
以替换文件方式进行,文件包括:
# 自己写的脚本
i18n-zunui.sh
# js的国际化文件
djangojs.po
# py的国际化文件
django.po
# 容器详情中,console标签页的controller文件
console.controller.js
# cloud-shell的controller文件,未使用,找到就一起改了。。。
cloud-shell.controller.js
覆盖的文件都修改了哪些内容?
django.po
py文件中要汉化的部分,主要是面板和面板组的汉化。
主要是在末尾添加了要汉化的内容。
djangojs.po
zun-ui的大部分页面都是使用angularjs写的,所以大部分列表中的文字都是在js/html中进行的国际化。
主要是在末尾添加了要汉化的内容。
console.controller.js
修改方法onGetContainer(response),对生成的dom元素中的文字进行国际化
function onGetContainer(container) {
//rwz add
var enableInteractiveModeTipStr = gettext("To display console," +
"interactive mode needs to be enabled when this container was created.");
var notRunningStr = gettext("Container is not running.");
ctrl.container = container.data;
var consoleUrl = webRoot + "containers/" + ctrl.container.id + "/console";
//var console = $("To display console, interactive mode needs to be enabled " +
// "when this container was created.");
var console = $(""
+ enableInteractiveModeTipStr + "");
if (ctrl.container.status !== "Running") {
//console = $("Container is not running.
");
console = $(""
+ notRunningStr +"");
} else if (ctrl.container.interactive) {
console = $("");
}
$("#console").append(console);
}
function onGetContainer(response) {
ctrl.container = response.data;
//rwz add
var enableInteractiveModeTipStr = gettext("To display console," +
"interactive mode needs to be enabled when this container was created.");
var notRunningStr = gettext("Container is not running.Please wait for starting up container.");
// attach console to existing container
ctrl.consoleUrl = webRoot + "containers/" + ctrl.container.id + "/console";
//var console = $("To display console, interactive mode needs to be enabled " +
// "when this container was created.");
var console = $(""
+ enableInteractiveModeTipStr + "");
if (ctrl.container.status !== "Running") {
//console = $("Container is not running. Please wait for starting up container.
");
console = $(""
+ notRunningStr + "");
} else if (ctrl.container.interactive) {
console = $("");
// execute openrc.sh on the container
var command = "sh -c 'printf \"" + cloudsYaml + "\" > ~/.config/openstack/clouds.yaml'";
zun.executeContainer(ctrl.container.id, {command: command}).then(function() {
var command = "sh -c 'printf \"export OS_CLOUD=openstack\" > ~/.bashrc'";
zun.executeContainer(ctrl.container.id, {command: command}).then(function() {
angular.noop();
});
});
}
// append shell content
angular.element("#shell-content").append(console);
}
po文件位置:
/openstack/venvs/horizon-18.1.5/lib/python2.7/site-packages/openstack_dashboard/locale/zh_CN/LC_MESSAGES/
zun-ui目录位置:
/openstack/venvs/horizon-18.1.5/lib/python2.7/site-packages/zun_ui/
查找源文件中涉及国际化的部分:
py、js文件中调用gettext()方法,html使用translate标记的的部分,结合出现位置上下文进行翻译。
其中,js文件和html文件的翻译要放到djangojs.po文件中,py文件的翻译要放到django.po文件中。
对于没有使用国际化方法,直接在页面中显示英文的情况,根据需要决定是否修改代码,以支持国际化。
使用msgctxt标记,添加上下文信息。
相应的,gettext方法要换为ngettext方法。(未验证)
po文件写法 :
msgctxt "month name"
msgid "May"
msgstr ""
template写法:
{% trans "May" context "month name" %}
参考:python 国际化一词多义翻译
对于直接输出到页面的,如:
zun_ui/static/dashboard/container/containers/details/console.controller.js
zun_ui/static/cloud-shell/cloud-shell.controller.js
需要适当修改代码,调用gettext方法,已实现国际化。
对于从api中获去数据的,如:
zun_ui/static/dashboard/container/containers/containers.module.js
需要增加filter来处理国际化的信息。
//angular.module**** 的最后追加
.filter('translatetext', getTranslateText)
//containerProperties()方法中,对于未被正确翻译的字段,如status,添加filter
'status': {label: gettext('Status'), filters: ['noValue', 'translatetext'] },
function getTranslateText() {
return function(input){
return gettext(input);
}
}
这里,可以根据具体需要,添加合适的国际化/过滤操作。
形如:
<p translate>
When the <b>Admin Stateb> for a network is set to <b>Upb>,
then the network is available for use. You can set the <b>Admin Stateb> to <b>Downb>
if you are not ready for other users to access the network.
p>
在翻译时,msgid中的内容要保留html中的格式,包括空格,换行,首尾可以不管。
msgid ""
"When the Admin State for a network is set to Up,\n"
" then the network is available for use. You can set the Admin State"
"b> to Down\n"
" if you are not ready for other users to access the network."
msgstr ""
"当网络的管理状态被设置为正常,\n"
"网络将会是可用的。如果您还没有准备让别人访问该网络,\n"
"可以把管理状态设置为停止。"