Wordpress是一個(gè)非常不錯(cuò)的blog系統(tǒng),使用方便,且能更換不同的主題。在國外的網(wǎng)站上,有很多免費(fèi)的主題,這些主題不但表現(xiàn)形式漂亮、簡潔,而且代碼也非常精煉。
但我們國人在使用這些主題的時(shí)候,都不免要碰到一個(gè)漢化的問題。最直接的辦法,當(dāng)然是打開文本編輯器,將這些主題的模板文件進(jìn)行修改,將英文的地方替換成中文。但這樣的做法,雖然直接,存在的缺點(diǎn)也是很明顯的:首先,我們需要了解我們文本編輯器最后保存文件時(shí)的編碼,并且要符合Wordpress生成頁面時(shí)產(chǎn)生的charset屬性,如果你的文本編輯器保存文件為GB2312,而Wordpress設(shè)置成了UTF-8,那么頁面顯示出來就是亂碼。其次,我們直接改動了原來的主題代碼,增加了程序和相應(yīng)語言的耦合度,不便于維護(hù),以后如果主題的作者對主題代碼進(jìn)行了升級,我們就需要重新進(jìn)行修改了。最后,對于那些追求完美的程序員來說,更趨向于低耦合度的東西。
其實(shí),Wordpress利用了GNUgettext模塊,已經(jīng)完美地支持了多語言。而很多國外的優(yōu)秀主題,也是遵循這樣的規(guī)范進(jìn)行開發(fā)的,我們所需要做的就是,生成一張翻譯列表,然后填上我們的漢語對應(yīng)語句就可以了。當(dāng)然,你的主題如果不準(zhǔn)備更新,或者追求快速(畢竟翻譯的步驟還是比直接修改來的麻煩一點(diǎn)),你也可以跳過本文。
在開始本文的實(shí)驗(yàn)以前,請確保你已經(jīng)知道以下事情:
wp-config.php
文件里的WPLANG定義為’zh_CN’,其中zh代表中文,CN代表中國大陸。然后下載安裝Wordpress的mo文件到wp-content/language
目錄下。sidebar.php
文件。好了,首先,我們到這里下載一個(gè)用于測試的主題。這個(gè)主題叫做Barthelme,是一個(gè)符合Wordpress 2.5規(guī)范的主題,非常簡潔的主題,下面是它的預(yù)覽:
另外插句話,http://www.plaintxt.org/ 這個(gè)網(wǎng)站里面提供了幾個(gè)非常簡潔的主題,而且都支持Wordpress 2.5,喜歡這種風(fēng)格的朋友可以自行選擇。
好了,我們按照常規(guī)辦法安裝好 Barthelme 主題。由于我們已經(jīng)將Wordpress切換到了中文,所以我們可以看到這樣的模樣:
我們看看這個(gè)主題截圖,其中少部分被正常翻譯了,比如“頁面”,然而更多的詞條還沒有被翻譯,比如“CATEGORIES“和”Comments“等。這是怎么回事呢?原來我們由于安裝過Wordpress的漢化mo文件,并且將站點(diǎn)切換到了zh_CN,所以這些詞條首先從Wordpress的漢化mo文件里尋找,這樣,它找到了“頁面”詞條的翻譯,但卻沒有找到“CATEGORIES“詞條的翻譯,于是產(chǎn)生了這樣奇怪的現(xiàn)象。
到這里,我們應(yīng)該看到一個(gè)問題,那就是,新的模板(符合多語言開發(fā)規(guī)范的模板)會自動進(jìn)入Wordpress的漢化包里進(jìn)行詞條翻譯搜索,這樣,就和Wordpress的翻譯混雜在了一起。我們知道,Wordpress的中文漢化主要應(yīng)該集中于后臺管理的漢化,而對于主題,理想的狀況是每個(gè)主題有自己的漢化包。
為了解決這個(gè)問題,Wordpress提出了文字域的概念。用過C++語言的朋友可以將其對應(yīng)于namespace概念。這個(gè)概念解決了作用域的沖突。好,那么我們首先為Barthelme主題添加其獨(dú)自的文字域。
我們進(jìn)入wp-content/themes/barthelme
目錄,打開functions.php
文件。functions.php
文件是wordpress主題的一個(gè)標(biāo)準(zhǔn)文件,主要用來定義一些該主題的php函數(shù)以及進(jìn)行一些環(huán)境的設(shè)置。我們在該文件的最后部分發(fā)現(xiàn)了這樣的代碼:
load_theme_textdomain('barthelme')
load_theme_textdomain
函數(shù)用來設(shè)置主題的域。我們看到,Barthelme主題是嚴(yán)格按照多語言標(biāo)準(zhǔn)進(jìn)行開發(fā)的,它已經(jīng)為我們設(shè)置好了域名:barthelme。在漢化其他主題時(shí),如果我們沒有發(fā)現(xiàn)這條語句,可以在functions.php
文件里添加這條語句,并定義自己的域名。
既然定義了域名,那么為什么詞條“頁面”能夠正確翻譯,而“Categories“就不能了呢?讓我們打開sidebar.php
文件,找到以下部分:
<?php wp_list_pages('title_li=<h3>'.__('Pages').'</h3>&sort_column=menu_order') ?>
<li id="categories">
<h3><?php _e('Categories', 'barthelme'); ?></h3>
<ul>
<?php wp_list_cats('sort_column=name&hierarchical=1') ?>
</ul>
</li>
原來,在顯示詞條”頁面“時(shí),用的是__('Pages')
,而顯示詞條“分類”時(shí),用的是_e('Categories', 'bathelme')
; 我們知道,php里主要通過__(key,domain)
和_e(key,domain)
來進(jìn)行詞條翻譯,而當(dāng)我們不提供第二個(gè)參數(shù)時(shí),則在全局域里進(jìn)行搜索,這就是為什么我們的“頁面”詞條可以正常顯示的原因,因?yàn)檫@里遺漏了域名,wordpress進(jìn)入全局域里為其搜索去了??磥?,這里是bug了,對其進(jìn)行修改:__('Pages', 'barthelme')
。然后保存后,刷新下頁面:
這樣,詞條“頁面”就不會被翻譯了,因?yàn)槲覀冞€沒有提供該域的翻譯文件。
接下來要進(jìn)行翻譯了,我們首先需要產(chǎn)生一個(gè)翻譯詞條的列表,也就是po文件(或者pot文件,pot的意思是po文件的模板template)。當(dāng)然,我們?nèi)绻止ぎa(chǎn)生這個(gè)列表的話,工作量是非常巨大的,這里我們借助GNU gettext的工具來產(chǎn)生:
] cd wp-content/themes/barthelme
] find . -iname "*.php" > files.tmp
] xgettext --language=PHP --indent --keyword=__ --keyword=_e
--keyword=__ngettext:1,2 -s -n --from-code=UTF-8 -f files.tmp
] rm files.tmp
我們首先進(jìn)入主題目錄,通過find命令產(chǎn)生一個(gè)php文件名列表,并將這個(gè)文件名列表保存為一個(gè)臨時(shí)文件files.tmp
。接著,我們用xgettext文件來掃描php文件,自動產(chǎn)生po文件。你可以通過 info xgettext
來獲取詳細(xì)的使用幫助,其中--indent
選項(xiàng)指定使用縮進(jìn)模式,-s
選項(xiàng)指定對詞條進(jìn)行排序,-n
選項(xiàng)則將每個(gè)詞條所處的位置添加到該詞條的注釋里。
運(yùn)行完xgettext后,會產(chǎn)生一個(gè)messages.po
文件,這就是我們需要工作的翻譯文件。它主要由兩部分組成:頭信息和翻譯詞條列表。我們打開這個(gè)文件,它的開始部分是一個(gè)頭信息部分:
msgid ""
msgstr "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-04-09 18:51+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
我們首先需要對這個(gè)頭信息進(jìn)行改造,改造有兩個(gè)部分:一,設(shè)置charset,這個(gè)一般設(shè)置為UTF-8;二來要為其添加關(guān)于漢語的一些細(xì)節(jié)。關(guān)于語言的細(xì)節(jié)主要包括nplurals和plural的設(shè)置,其實(shí)它包括了該語言如何處理單數(shù)和復(fù)數(shù)的情況,當(dāng)然,我們漢語沒有這個(gè)問題,我們簡單地將nplurals設(shè)置為2,plural設(shè)置為1就可以了。下面是修改好的頭信息(注意紅色部分):
msgstr "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-04-09 18:51+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=1 != 1;\n"
接下來,該翻譯了,我們搜索以下詞條,并將其翻譯:
#: sidebar.php:11
msgid "Pages"
msgstr "頁面"
#: sidebar.php:14
msgid "Categories"
msgstr "分類"
保存文件的時(shí)候,我們要注意,因?yàn)槲覀円呀?jīng)設(shè)置編碼為UTF-8,所以我們需要將文件保存為UTF-8編碼,常用的編輯器,比如UtralEdit和Emacs都支持的。保存好后我們需要將messages.po
文件重新命名為zh_CN.po
:
] mv messages.po zh_CN.po
接下來編譯這個(gè)po文件為mo文件:
] msgfmt -o zh_CN.mo zh_CN.po
好了,檢查以下我們的主題目錄,是否有一個(gè)名為zh_CN.mo
文件,如果有,說明一切正常,我們刷新一下頁面:
翻譯成功!接下來要做的就是,繼續(xù)修改po文件,翻譯詞條,然后用msgfmt工具對其進(jìn)行編譯即可。
總結(jié)
一個(gè)符合gettext規(guī)范的主題需要注意以下內(nèi)容(針對Wordpress 2.5):
functions.php
文件里設(shè)置文字域 load_theme_textdomai('mydomain')
;__('key','mydomain')
或者_e('key','mydomain')
;zh_CN.po
;zh_CN.po
文件,翻譯各個(gè)詞條;