為了使您的應用程序中的字符串可以翻譯,您必須將原始字符串打包到一組特殊功能的調用中。
## Gettext簡介
WordPress使用i18n的gettext庫和工具。 如果你在網上看,你會看到`_()`函數,它引用了本地PHP gettext兼容的翻譯功能。 使用WordPress,您應該使用`__()`WordPress定義的PHP函數。 如果您想獲得更廣泛和更深入的gettext視圖,我們建議您閱讀gettext在線手冊。
## 文字域
使用文本域來表示屬于該插件的所有文本很重要。 文本域是唯一的標識符,可以確保WordPress能夠區分所有加載的翻譯。 這增加了可移植性,并通過已經存在的WordPress工具更好地發揮作用。 文本域必須與插件的插槽相匹配。 如果您的插件是一個名為my-plugin.php的文件,或者它包含在一個名為my-plugin的文件夾中,則域名應為my-plugin。 如果您的插件托管在wordpress.org上,那么它必須是插件URL(wordpress.org/plugins/ <slug>)中的一小部分。
文本域名必須使用破折號而不是下劃線。
字符串示例:
```
__( 'String (text to be internationalized)', 'text-domain' );
```
將“文本域”更改為插件的插件。
>[warning] 警告:不要在gettext函數的文本域部分使用變量名。 不要做這個快捷方式:__('Translate me。',$ text_domain);
文本域也需要添加到插件頭。 即使插件被禁用,WordPress也使用它來國際化你的插件元數據。 文本域應與加載文本域時使用的文本域相同。
標題示例:
```
/*
* Plugin Name: My Plugin
* Author: Plugin Author
* Text Domain: my-plugin
*/
```
## 域路徑
使用域路徑,以便當插件被禁用時,WordPress知道在哪里找到翻譯。 僅當翻譯位于單獨的語言文件夾中時才有用。 例如,如果.mo文件位于languages文件夾中,則Domain Path將是“/languages”,必須用第一個斜杠寫入。 默認為插件的languages文件夾:
標題示例:
```
/*
* Plugin Name: My Plugin
* Author: Plugin Author
* Text Domain: my-plugin
* Domain Path: /languages
*/
```
## 基本字符串
最常用的是`__()`。 它只是返回其參數的翻譯:
```
__( 'Blog Options', 'my-plugin' );
```
另一個簡單的是_e(),它輸出其參數的翻譯。 而不是寫:
```
echo __( 'WordPress is the best!', 'my-plugin' );
```
你可以使用較短的:
```
_e( 'WordPress is the best!', 'my-plugin' );
```
## 變量
如果您在字符串中使用變量,如下面的示例,您將使用占位符。
```
echo 'Your city is $city.'
```
解決方案是使用printf系列函數。 特別有用的是printf和sprintf。 以下是正確的解決方案:
```
printf(
/* translators: %s: Name of a city */
__( 'Your city is %s.', 'my-plugin' ),
$city
);
```
>[warning] 請注意,這里的翻譯字符串只是模板“你的城市是%s”,這在源代碼和運行時都是一樣的。
如果字符串中有多個占位符,建議您使用參數交換。 在這種情況下,單引號(')是強制性的:雙引號(“)將告訴php將$ s解釋為s變量,這不是我們想要的。
```
printf(
/* translators: 1: Name of a city 2: ZIP code */
__( 'Your city is %1$s, and your zip code is %2$s.', 'my-plugin' ),
$city,
$zipcode
);
```
這里的郵政編碼正在城市名后顯示。 在某些語言中,以相反的順序顯示郵政編碼和城市更為合適。 在上面的例子中使用%s的前綴,就允許這樣的情況。 因此,翻譯可以寫成:
```
printf(
/* translators: 1: Name of a city 2: ZIP code */
__( 'Your zip code is %2$s, and your city is %1$s.', 'my-plugin' ),
$city,
$zipcode
);
```
重要! 此代碼不正確。
```
// This is incorrect do not use.
_e( "Your city is $city.", 'my-plugin' );
```
翻譯的字符串是從源中提取出來的,所以翻譯人員會得到這個短語:“你的城市是$ city”。
但是在應用程序中,將會被稱為“你的城市是倫敦”。 gettext將不會找到適合的翻譯,并返回其論點:“你的城市是倫敦”。 不幸的是,它沒有正確翻譯。
# 多個
##基本多元化
如果在項目數量更改時有變化的字符串。 在英語中你有“一個評論”和“兩個意見”。 在其他語言中,您可以有多個復數形式。 要在WordPress中處理這個問題,可以使用_n()函數。
```
printf(
_n(
'%s comment',
'%s comments',
get_comments_number(),
'my-plugin'
),
number_format_i18n( get_comments_number() )
);
```
_n() 接受4個參數:
- singular – 字符串的單數形式(注意,它可以用于某些語言中的一個以外的數字,因此應使用“%s項”而不是“一個項”)
- plural – 字符串的復數形式
- count – 對象的數量,這將決定是否應該返回單數或復數形式(有多種語言,有兩種以上的形式)
- text domain – 插件文本域
功能的返回值是正確的翻譯形式,對應于給定的計數。
##稍后完成
您首先使用_n_noop()或_nx_noop()設置多個字符串。
```
$comments_plural = _n_noop(
'%s comment.',
'%s comments.'
);
```
然后在稍后的代碼中,您可以使用translate_nooped_plural()來加載字符串。
```
printf(
translate_nooped_plural(
$comments_plural,
get_comments_number(),
'my-plugin'
),
number_format_i18n( get_comments_number() )
);
```
## 背景消歧
有時一個術語在多個語境中被使用,雖然它是英文中同一個詞,但是在其他語言中它必須被不同地翻譯。 例如,Post可以用作動詞“點擊這里發表你的評論”,作為名詞“編輯這篇文章”。 在這種情況下,應該使用_x()或_ex()函數。 它類似于__()和_e(),但它有一個附加的參數 - 上下文:
```
_x( 'Post', 'noun', 'my-plugin' );
_x( 'Post', 'verb', 'my-plugin' );
```
在這兩種情況下使用此方法,我們將獲得原始版本的字符串注釋,但翻譯器將看到兩個用于翻譯的注釋字符串,每個字符串在不同的上下文中。
>[info] 請注意,與`__()`類似,`_x()`具有回調版本:`_ex()`。 前面的例子可以寫成:
```
_ex( 'Post', 'noun', 'my-plugin' );
_ex( 'Post', 'verb', 'my-plugin' );
```
使用您覺得增強易讀性和易于編碼的任何一個。
##說明
所以翻譯人員知道如何翻譯一個字符串__('g:i:s a'),你可以在源代碼中添加一個澄清的注釋。 它必須從翻譯人員開始:在gettext調用之前成為最后一個PHP注釋。 這是一個例子:
```
/* translators: draft saved date format, see http://php.net/date */
$saved_date_format = __( 'g:i:s a' );
```
它還用于解釋字符串中的占位符,如_n_noop(`<strong>版本%1 $ s </ strong>`已解決%2 $ s錯誤,`<strong>版本%1 $ s </ strong>` “解決了%2 $ s的錯誤”)。
```
/* translators: 1: WordPress version number, 2: plural number of bugs. */
_n_noop( '<strong>Version %1$s</strong> addressed %2$s bug.',
'<strong>Version %1$s</strong> addressed %2$s bugs.' );
```
## 換行字符
Gettext不喜歡\ r(ASCII碼:13)在可翻譯的字符串,所以請避免它,并使用\ n代替。
##空字符串
空字符串保留用于內部Gettext使用,您不得嘗試將空字符串國際化。 它也沒有任何意義,因為翻譯者不會看到任何上下文。
如果您有一個有效的用例來使一個空字符串國際化,請添加上下文以幫助翻譯人員,并與Gettext系統保持一致。
## 處理JavaScript文件
使用wp_localize_script()將已翻譯的字符串或其他服務器端數據添加到先前排入的腳本。
##轉義字符串
逃避所有的字符串是好的,這樣翻譯者就不能運行惡意代碼。 有幾個與國際化功能相結合的逃生功能。
##本地化功能
##基本功能
- __()
- _e()
- _x()
- _ex()
- _n()
- _nx()
- _n_noop()
- _nx_noop()
- translate_nooped_plural()
##翻譯和退出功能
必須轉義需要翻譯并在html標簽的屬性中使用的字符串。
- esc_html__()
- esc_html_e()
- esc_html_x()
- esc_attr__()
- esc_attr_e()
- esc_attr_x()
## 日期和數字功能
- number_format_i18n()
- date_i18n()
## 寫字符串的最佳做法
以下是編寫字符串的最佳做法
- 使用體面的英式風格 - 盡量減少俚語和縮寫。
- 使用整個句子 - 在大多數語言中,單詞順序與英語不同。
- 拆分段落 - 合并相關句子,但不要在一個字符串中包含整個文本頁面。
- 不要將前導或尾隨空格留在可翻譯的短語中。
- 假設翻譯時字符串的長度可以翻倍
- 避免不正常的標記和不尋常的控制字符 - 不要包含文本周圍的標簽
- 不要將不必要的HTML標記放入已翻譯的字符串中
- 不要留下翻譯的網址,除非他們可以使用其他語言的版本。
- 將變量作為占位符添加到字符串中,如在某些語言中,占位符更改位置。
```
printf(
__( 'Search results for: %s', 'my-plugin' ),
get_search_query()
);
```
使用格式字符串而不是字符串連接 - 翻譯短語而不是單詞 -
```
printf(
__( 'Your city is %1$s, and your zip code is %2$s.', 'my-plugin' ),
$city,
$zipcode
);
```
總是比:
```
__( 'Your city is ', 'my-plugin' ) . $city . __( ', and your zip code is ', 'my-plugin' ) . $zipcode;
```
嘗試使用相同的單詞和相同的符號,因此不需要翻譯多個字符串,例如`__('Posts:','my-plugin');`和`__('Posts','my-plugin');`
##將文本域添加到字符串
您必須將您的文本域作為參數添加到每個__(),_e()和__n()gettext調用中,否則您的翻譯將無法正常工作。
例子:
```
__( 'Post' )
```
應該成為
```
__( 'Post', 'my-theme' )
```
```
_e( 'Post' )
```
應該成為
```
_e( 'Post', 'my-theme' )
```
```
_n( 'One post', '%s posts', $count )
```
應該成為
```
_n( 'One post', '%s posts', $count, 'my-theme' )
```
如果您的插件中也有用于WordPress核心的字符串(例如“設置”),那么您還應該添加自己的文本域,否則如果核心字符串發生變化(如果發生),那么它們將變為非翻譯。
手動添加文本域可能是一個負擔,如果不是在編寫代碼時連續完成,這就是為什么你可以自動執行:
如果您的插件位于WordPress.org插件目錄中,請轉到您的“管理”頁面,然后滾動到“添加域到Gettext呼叫”。
上傳要添加文本域的文件。
點擊“獲取域文件”。
WordPress.org Plugin Admin區域
WordPress.org Plugin Admin區域
除此以外:
將add-textdomain.php腳本下載到要添加文本域的文件夾
在命令行中移動到文件所在的目錄
運行此命令創建一個添加了文本域的新文件
```
php add-textdomain.php my-plugin my-plugin.php > new-my-plugin.php
```
如果您希望將add-textdomain.php放在不同的文件夾中,那么您只需要在命令中定義位置。
```
php \path\to\add-textdomain.php my-plugin my-plugin.php > new-my-plugin.php
```
如果您不想輸出新文件,請使用此命令。
```
php add-textdomain.php -i my-plugin my-plugin.php
```
如果要更改目錄中的多個文件,還可以將目錄傳遞給腳本。
```
php add-textdomain.php -i my-plugin my-plugin-directory
```
完成后,文本域將被添加到文件中所有gettext調用的末尾。 如果存在現有的文本域,則不會被替換。
## 加載文本域
>[warning] 注意:WordPress 4.6出來之后,翻譯現在以translate.wordpress.org為優先,因此通過translate.wordpress.org翻譯的插件不再需要load_plugin_textdomain()了。
如果您不想在您的插件中添加一個load_plugin_textdomain()調用,則必須將readme.txt中的至少要求至少為:。
您需要使用插件的翻譯加載MO文件。 您可以通過調用函數load_plugin_textdomain()來加載它們。 此調用從插件的基本目錄載入{text-domain} - {locale} .mo。 語言環境是常規設置下的站點語言設置的語言代碼和/或國家/地區代碼。 有關語言和國家/地區代碼的更多信息,請參閱您的語言中的WordPress。
從上面的代碼示例,文本域是my-plugin,因此德語MO和PO文件應該命名為my-plugin-de_DE.mo和my-plugin-de_DE.po。
例:
```
function my_plugin_load_plugin_textdomain() {
load_plugin_textdomain( 'my-plugin', FALSE, basename( dirname( __FILE__ ) ) . '/languages/' );
}
add_action( 'plugins_loaded', 'my_plugin_load_plugin_textdomain' );
```
## 語言包
如果您對語言包感興趣,以及如何進行translate.wordpress.org的導入,請閱讀關于翻譯的Meta手冊頁面。
- 簡介
- 主題開發
- WordPress許可證
- 什么是主題
- 開發環境
- 主題開發示例
- 主題基礎
- 模板文件
- 主樣式表(style.css)
- 文章類型
- 規劃主題文件
- 模板層級
- 模板標簽
- 循環
- 主題函數
- 連接主題文件和目錄
- 使用CSS和JavaScript
- 條件標簽
- 類別,標簽和自定義分類
- 模板文件
- 內容模板文件
- 頁面模板文件
- 附件模板文件
- 自定義內容類型
- 部分和其他模板文件
- 評論模板
- 分類模板
- 404頁面
- 主題功能
- 核心支持的功能
- 管理菜單
- 自定義Headers
- 自定義Logo
- 文章格式
- 置頂文章
- Sidebars
- Widgets
- 導航菜單
- 分頁
- 媒體
- Audio
- Images
- Galleries
- Video
- 精選圖片和縮略圖
- 國際化
- 本地化
- 輔助功能
- 主題選項 – 自定義API
- 定制對象
- 改進用戶體驗的工具
- 定制JavaScript API
- JavaScript / Underscore.js渲染的自定義控件
- 高級用法
- 主題安全
- 數據消毒/逃避
- 數據驗證
- 使用隨機數
- 常見漏洞
- 高級主題
- 子主題
- UI最佳實踐
- JavaScript最佳做法
- 主題單元測試
- 驗證你的主題
- Plugin API Hooks
- 發布你的主題
- 所需的主題文件
- 測試
- 主題評論指南
- 寫文檔
- 提交你的主題到WordPress.org
- 參考文獻
- 模板標簽列表
- 條件標簽列表
- 編碼標準
- HTML編碼標準
- CSS編碼標準
- JavaScript編碼標準
- PHP編碼標準
- 插件開發
- 插件開發簡介
- 什么是插件
- 插件基礎
- 頭部要求
- 包括軟件許可證
- 啟用 / 停用 Hooks
- 卸載方法
- 最佳做法
- 插件安全
- 檢查用戶功能
- 數據驗證
- 保護輸入
- 保護輸出
- 隨機數
- Hooks
- Actions
- Filters
- 自定義Hooks
- 高級主題
- 管理菜單
- 頂級菜單
- 子菜單
- 短代碼
- 基本短碼
- 封閉短碼
- 帶參數的短代碼
- TinyMCE增強型短碼
- 設置
- 設置API
- 使用設置API
- 選項API
- 自定義設置頁面
- 元數據
- 管理帖子元數據
- 自定義元數據
- 渲染元數據
- 自定義文章類型
- 注冊自定義文章類型
- 使用自定義文章類型
- 分類
- 使用自定義分類
- 在WP 4.2+中使用“split術語”
- 用戶
- 創建和管理用戶
- 使用用戶元數據
- 角色和功能
- HTTP API
- JavaScript
- jQuery
- Ajax
- 服務器端PHP和入隊
- Heartbeat API
- 概要
- 計劃任務
- 了解WP-Cron計劃
- 安排WP-Cron 事件
- 將WP-Cron掛接到系統任務計劃程序中
- WP-Cron簡單測試
- 國際化
- 本地化
- 如何國際化您的插件
- 國際化安全
- WordPress.org
- 詳細插件指南
- 規劃您的插件
- 如何使用Subversion
- 插件開發者常見問題
- 開發工具
- Debug Bar 和附加組件
- 輔助插件
- REST API手冊
- 資源
- 文章
- 文章修訂
- 文章類型
- 文章狀態
- 類別
- 標簽
- 頁面
- 評論
- 分類
- 媒體
- 用戶
- 設置
- 使用REST API
- 全局參數
- 分頁
- 鏈接和嵌入
- 發現
- 認證
- 經常問的問題
- 骨干JavaScript客戶端
- 客戶端庫
- 擴展REST API
- 添加自定義端點
- 自定義內容類型
- 修改回應
- 模式
- 詞匯表
- 路由和端點
- 控制器類