ZUN UI國際化

實施操作

控制節點


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 = $("<p>To display console, interactive mode needs to be enabled " +
      //  "when this container was created.</p>");
      var console = $("<p>" + enableInteractiveModeTipStr + "</p>");
      if (ctrl.container.status !== "Running") {
        //console = $("<p>Container is not running.</p>");
        console = $("<p>"+ notRunningStr +"</p>");
 
      } else if (ctrl.container.interactive) {
        console = $("<iframe id=\"console_embed\" src=\"" + consoleUrl +
        "\" style=\"width:100%;height:100%\"></iframe>");
      }
      $("#console").append(console);
    }
  • cloud-shell.controller.js
    修改方法onGetContainer(response),對生成的dom元素中的文字進行國際化
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 = $("<p>To display console, interactive mode needs to be enabled " +
      //  "when this container was created.</p>");
      var console = $("<p>" + enableInteractiveModeTipStr + "</p>");
      if (ctrl.container.status !== "Running") {
        //console = $("<p>Container is not running. Please wait for starting up container.</p>");
        console = $("<p>" + notRunningStr + "</p>");
      } else if (ctrl.container.interactive) {
        console = $("<iframe id=\"console_embed\" src=\"" + ctrl.consoleUrl +
          "\" style=\"width:100%;height:100%\"></iframe>");
 
        // 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);
    }
}

這裏,可以根據具體需要,添加合適的國際化/過濾操作。

html中的多行內容

形如:

  <p translate>
    When the <b>Admin State</b> for a network is set to <b>Up</b>,
    then the network is available for use. You can set the <b>Admin State</b> to <b>Down</b>
    if you are not ready for other users to access the network.
  </p>

在翻譯時,msgid中的內容要保留html中的格式,包括空格,換行,首尾可以不管。

msgid ""
"When the <b>Admin State</b> for a network is set to <b>Up</b>,\n"
"    then the network is available for use. You can set the <b>Admin State</"
"b> to <b>Down</b>\n"
"    if you are not ready for other users to access the network."
msgstr ""
"當網絡的<b>管理狀態</b>被設置爲<b>正常</b>,\n"
"網絡將會是可用的。如果您還沒有準備讓別人訪問該網絡,\n"
"可以把<b>管理狀態</b>設置爲<b>停止</b>。"
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章