很多時候在漢化插件的地方會遇到一些困難,那就是在插件原始碼中包含了韓文訊息,一方面當然是不希望直接使用中文來代替韓文,另一方面在不使用直接取代的狀況下很多地方又有其難度。這裡提供在我個人漢化插件的一些小技巧,給大家參考。

在 index.xml 這個檔案裡面,有 4 種標籤是可以加上 xml:lang 這個 attriubute 的,且 TT/TC 也能看得懂。
  1. <title>,插件標題
  2. <description>,插件描述
  3. <author>,插件作者
  4. <config>,插件設定頁面內容,在插件啟用時,會呼叫這裡面的設定。
一般比較簡易的插件,最主要是以這四種標籤來做到插件的資料設定。比較複雜一點的插件,會使用呼叫函式的方式,將設定的頁面交給 index.php 裡面的函式去做,而,使用呼叫函式的方式,就不能在 index.xml 裡面設定語言檔了,這個時候就要對 index.php 動手腳。

以我自己寫的 SItemap_XML 這個插件來說,我在 index.xml 中使用了 <adminMenu> 且用 <handler> 呼叫了 index.php 裡面的一個 sitemap_Manager 函式,由這一個函式來產生所需要的設定畫面。再舉一例,以 JP_ThumbnailListViewTT 這個插件來說,他是使用 <config> 標籤,以 manifestHandler 這個 Attribute 呼叫了 CFG_ThumbnailSet 函式,來產生設定畫面。

不管是我呼叫的 sitemap_Manager 或是 JP 呼叫的 CFG_ThumbnailSet 函式,這樣的呼叫方式都會遇到一個問題,就是沒辦法單純的從 index.xml 中設定語言。這個時候,我們來看看 index.php 到底可以怎麼改。

在 TC 1.6 版之後,要獲取使用者所設定的語言到底是什麼,可以使用這幾種方法:
  1. 先 global $blog, service;
    然後使用 $blog['blogLanguage'] 或是 $service['language'] 取得
  2. 先 requireComponent("Textcube.Function.Setting");
    直接使用 TC 的預設函式 setting::getBlogSetting('language') 或是 getBlogSetting('language') 取得
在取得使用者的語言設定之後,你就可以依照這些語言設定去設定陣列。這裡有一個偷吃步的方式,我從 /lib/locale.php 中的字串轉換函式 _t 與 _f 中改寫成自己可以設定字串並轉換的函式。所以,如果要在插件中使用自己設定的 language 檔案,就必須要用這樣的函式來模擬 TC 將 __text 轉換成我們要的字串。

// 將普通字串做轉換
function _myts($t) {
    global $__ts;
    if (isset($__ts[$t])) {
        return $__ts[$t];
    } else {
        return $t;
    }
}
// 將自帶變數字串做轉換
function _myfs($t) {
    $t = get_ts($t);
    if (func_num_args() <= 1) {
        return $t;
    } else {
        for ($i = 1; $i < func_num_args(); $i++) {
            $arg = func_get_arg($i);
            $t = str_replace('%' . $i, $arg, $t);
        }
        return $t;
    }
}

這兩個函式就是轉換字串使用的。然後,你需要建立一個檔案,這個檔案可以放在跟插件同一層資料夾,或者是,你可以跟我一樣在插件資料夾中建立一個 lang 資料夾,然後使用 require_once 的方式將語言檔轉入。

// 整體宣告,$__ts 是語言檔所使用的陣列
global $blog, $service, $__ts;

// 取得語言設定
if (!isset($blog['blogLanguage'])) {
    $blog['blogLanguage'] = $service['language'];
}

// 設定語言檔案路徑
switch($blog['blogLanguage']) {
    case "zh-TW":
    case "zh-CN":
        $languageFile = 'lang/'.$blog['blogLanguage'].'.php';
    break;
    default:
        $languageFile = "";
}
// 取得語言檔案
if(!empty($languageFile)) { require($languageFile); }

語言檔案的名稱要以 TC 的設定去做設定,像是 ko.php, zh-TW.php, zh-CN.php 等等,檔案的內容很簡單。以 JP_Thumbnail 那個插件為例子,那麼 zh-CN.php 的內容就是。


<?php  // 简体中文

/* zh-CN */
$__ts = array();
$__ts['에 해당되는 글 [##_list_count_##]건'] = '目前共有 [##_list_count_##] 則';
$__ts['보호되어 있는 글입니다.'] = '被保护的文章。';
$__ts['썸네일 이미지를 사이드바에 출력하여 보여 줍니다.'] = '在预览模式以缩图的形式输出展示.';
...(後面省略)
?>

最後,你要把 index.php 檔案中,所有被設定在語言檔案裡面的字串,一字不漏的用 _myts('字串') 給包起來,如果只是純粹的字串轉換,那麼使用 _myts() 即可,例如:

原本字串是:보호되어 있는 글입니다.
要改為這樣:_myts('보호되어 있는 글입니다.');
前端就會被轉換顯示為:被保护的文章。

假設有使用到變數,就要使用 _myfs() 來做轉換,例如:

原本字串是:에 해당되는 글 '.$itemCount.' 건
要改為這樣:_myfs('에 해당되는 글 %1 건', $itemCount);
前端就會被轉換顯示為:目前共有 $itemCount 則
當然,在前端 $itemCount 這個 php 變數會被轉換成數值或字串,倘若你有很多個變數,那就用 %1, %2, %3 依此類推。

說了這麼多,希望各位在漢化插件的時候能有所應用。

個人是不建議將漢化的字典加入原本的語言檔案裡面。因為原本的語言檔案,他會將整個語言檔寫入前端頁面,會使用非常大量的 javascript 資源,對於 Client 端來說並不是一件好事,對於 Servlet 端來說,也會造成一些無謂的流量浪費。

像是之前改的 FM_Modren 這個插件來說,雖然它是不可關閉插件,但是,這個插件所使用的語言設定,對於非博客管理員來說並不需要,也就不用導入前端頁面。但是因為寫入原本語言檔的關係,他依舊被導入了前端頁面,這點就有點多此一舉了。

必要的話,個人是傾向於將 FM_Modren 語言檔案額外去設定,一方面可以減輕整個博客的負擔,另一方面也許可以減少一點點流量吧。不過,由於整個 FM_Modren 到底用到多少語言設定,又,那些語言設定跟誰有重複使用,在這些狀況都不明的情況下,要改可能還是有相當難度啊。

将把此主题..