iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 28
1
自我挑戰組

WordPress 客製化從 0 開始系列 第 28

Day 28 幫 WordPress 佈景主題與外掛加上多國語系支援

大家好,我是 Eric。
因為昨天介紹 AJAX 把 MP 耗完了,我們今天來談點比較輕鬆的話題。截至昨天為止,我們接觸到的都是與 WordPress 前端、後端功能有關的函式。
今天,我們要進一步讓我們的外掛可以讓其他貢獻者本地化為當地語言。

如何將外掛或佈景主題本地化

WordPress 上有許多方便的外掛的開發者,都以英文為基本語言進行開發,因此不論是我們自己使用,或是要將網站交付給客戶時,有時會碰到「想要中文化」的需求。這時候我們可以選擇有中文本地化版本的外掛,或是透過 Poedit 這套工具翻譯外掛與佈景主題。
關於 Poedit 的使用方式,可以參考這篇文章,這裡不再贅述。
這邊提醒幾點注意事項:

  • 在開始每次的 WordPress 本地化專案前,一定先取得 .pot 檔,不要直接從 .mo 檔譯回
  • 如果只是自用無所謂,如果是要上傳至 WordPress 儲存庫中,至少要遵循標準詞彙
  • WordPress 從 5.0 開始,便出現了許多由存放於 JavaScript 靜態檔案的字串,如果希望翻譯這些在 JavaScript 中的字串,則需要搭配 WP-CLI 指令。
  • WordPress 真正讀取的是編譯過的 .mo 檔,不是 .po 檔。

將字串標記為可翻譯的字串

__( '欲翻譯字串', 'text-domain' );
_e( '欲翻譯字串,自帶 echo 功能', 'text-domain' );
_x( '欲翻譯特定情境字串', '字串使用情境', 'text-domain' );
esc_html__( '欲翻譯字串,會跳脫 HTML 標記', 'text-domain' );
esc_html_e( '會跳脫 HTML 標記,自帶 echo', 'text-domain' );
esc_html_x( '有情境字串', '字串使用情境', 'text-domain' );

在佈景主題與外掛的檔案標頭中,都會包含 text-domain 這個屬性。這個 text-domain 定義了你的上述語法中的 text-domain 值。舉例來說,Twenty Twenty 的 text-domaintwentytwenty,那麼在 Twenty Twenty 的 functions.php 中,可以看到開發者以下列的方式標記可翻譯的選單字串:

/* functions.php Line 249 */
/**
 * Register navigation menus uses wp_nav_menu in five places.
 */
function twentytwenty_menus() {

	$locations = array(
		'primary'  => __( 'Desktop Horizontal Menu', 'twentytwenty' ),
		'expanded' => __( 'Desktop Expanded Menu', 'twentytwenty' ),
		'mobile'   => __( 'Mobile Menu', 'twentytwenty' ),
		'footer'   => __( 'Footer Menu', 'twentytwenty' ),
		'social'   => __( 'Social Menu', 'twentytwenty' ),
	);

	register_nav_menus( $locations );
}

如果今天我們要翻譯的字串包含變數的話,我們需要透過 PHP 中的 printfsprintf 來拼湊字串,舉例來說,Twenty Twenty 的 template-parts/entry-author-bio.php 的第 17 行用以下的程式碼,讓系統可以翻譯帶有變數的字串:

<?php
    printf(
        /* translators: %s: Author name */
        __( 'By %s', 'twentytwenty' ),
        esc_html( get_the_author() )
    );
?>

透過 %s 這個預留位置 (placehoder),告訴系統 esc_html( get_the_author() ) 會回傳一個字串給 'By xxx' 這個字串。而我們在翻譯時,則可以翻譯成「由 %s 撰寫」或「作者: %s」。

讓佈景主題或外掛載入語系檔 (.mo)

除了在 WordPress 的 wp-content/languages/themes 或 wp-content/languages/plugins 中加入語系檔以外,要讓佈景主題與外掛能夠讀取語系檔,必須分別透過下列兩個勾點來完成:

佈景主題

add_action( 'after_setup_theme', 'mytheme_setup' );
function mytheme_setup() {
    /* mytheme 是 text-domain,/languages 則是佈景主題中存放語系檔的預設位置 */
    load_theme_textdomain( 'mytheme', get_template_directory() . '/languages' );
    /* mytheme 的子佈景主題則需要用 load_child_theme_textdomain */
    load_child_theme_textdomain( 'mytheme', get_stylesheet_directory() . '/languages' );
}

外掛

/* @link https://developer.wordpress.org/reference/functions/load_plugin_textdomain/ */
add_action( 'init', 'myplugin_load_textdomain' );  
/**
 * Load plugin textdomain.
 */
function myplugin_load_textdomain() {
  load_plugin_textdomain( 'myplugin', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' ); 
}

結語

今天花了一些時間介紹替外掛與佈景主題建置成可翻譯的環境,這個功能其實對大多數的使用者都相對陌生,但如果是有興趣要將 WordPress 外掛或佈景主題上架到儲存庫的人,這可以說是最後一塊需要具備的知識。
明天,我們會介紹起始佈景主題 (starter theme),並說明如何透過起始佈景主題,實作出一個「手刻」的佈景主題。

延伸閱讀

Internalization | Theme Developer Handbook
How to Internationalize Your Plugin | Plugin Developer Handbook
Translations - Make WordPress.org
wp i18n make-pot


上一篇
Day 27 WordPress 客製化:用 AJAX 製作無限捲動
下一篇
Day 29 WordPress 的起始佈景主題 (starter theme)
系列文
WordPress 客製化從 0 開始30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言