問題描述
只要建立一個 child-theme 就足夠了 – 讓我們在技術上說沒有新增任何其他東西,但最低限度的 style.css – 為 child-theme 自動使用 parent-theme 的翻譯?
child-theme/style.css
/**
* Theme Name: Child-Theme Child
* Theme URI: http://example.com/
* Description: Child theme for the Twentytwelve theme
* Author: Theme Author
* Author URI: http://example.com/
* Template: twentytwelve
* Version: 0.1.0
*/
二十二主題有標準的語言翻譯檔案。
如果這不會在我的網站上自動發生,那麼開始 trouble-shooting 的翻譯是什麼?
最佳解決方案
Is it enough to just create a child-theme – let’s say technically without adding anything else but the bare minimum style.css – to have the translation of the parent-theme being used automatically for the child-theme as well?
基本上,答案是 NO,… 但… 有一個選擇:
新增一個 mu-plugin 。
這個 (MU-) 外掛有幾件事情:
-
它以 20 的優先順序掛接到
after_setup_theme中,假設父文字域/i18n .mo 檔案以正確掛鉤的預設優先順序正確載入。 -
然後它檢索
instanceofWP_Theme– 在這種情況下是兒童主題。 -
然後它檢查是否真的有一個孩子主題在使用。
-
如果這是真的,那麼它只會從父檔案載入文字域。
實際上很容易,因為核心類對我們進行了大量的檢查:它檢索了父主題的另一個 WP_Theme 例項。然後檢查 TextDomain 標題是否已設定,使用:$current_theme->get( 'TextDomain' ); 。因此,這個遊戲有一個約定:這個外掛只能工作,如果父主題得到了一個 Text Domain 和 (!) 一個 Domain Path 標題集。
<?php
/**
* Plugin Name: (#113391) Parent Theme i18n Autoloader
* Description: Load Twenty12 Child theme translation files automagically from Parent
*/
add_action( 'after_setup_theme', 'wpse113391_parent_theme_i18n_autoloader', 20 );
function wpse113391_parent_theme_i18n_autoloader()
{
$current_theme = wp_get_theme();
if ( is_child_theme() )
$current_theme->parent()->load_textdomain();
}
現在這裡出現了問題:由 core 提供的預設/標準的二十*主題不 (!) 具有 Domain Path 標題條目。這是我們必須立即修復的東西,因為 load_theme_textdomain()其他搜尋不在父主題資料夾中的翻譯檔案,但是
-
首先在子主題資料夾:
get_stylesheet_directory().WP_Theme::get( 'DomainPath' ),這意味著 (A)Domain Path需要設定,它需要以斜槓為字首:/。 -
然後在子主題資料夾中:`get_stylesheet_directory() 。’/languages’ 。
-
並在
WP_LANGUAGE_DIR.'/themes'目錄中。
注意:我猜這只是”backwards compatibility” 永遠不會被修復的錯誤,換句話說,這意味著有一個錯誤,但可能已經有開發人員在使用它了。 :P
那還有另外一個問題。 WP_Theme 類方法 load_textdomain()內部透過 $path 到 load_theme_textdomain()。而這個引數是 $this->get_stylesheet_directory()。此方法返回 $this->theme_root . '/' . $this->stylesheet 。所以這個功能實際上會很好,但是它只是簡單地呼叫 get_stylesheet_directory()的內部替換 (這是可以過濾的) 。人們現在可以想想
“Hey! The class
implements ArrayAccess! So simply set the missing array key ofDomain Path!”
錯誤。所有類的屬性都標記為 private,無法訪問。
那你可能會想
“Why not simply
extendtheWP_Themeclass and define aset()Method so we can manually set the missing header entries?”
錯誤。該類本身是 final,不可擴充套件。
結果:我們留下了什麼 load_theme_textdomain() – 呼叫鏈中的最後一個功能 – 提供給我們。現在我們收到一個更大的外掛來攔截 load_theme_textdomain()呼叫來載入正確的檔案。為了不打擾其他 i18n 檔案載入,它會立即從過濾器中刪除回撥,以保持您的環境整潔。
<?php
/**
* Plugin Name: (#113391) Parent Theme i18n Autoloader
* Description: Load Twenty12 Child theme translation files automagically from Parent
*/
add_action( 'muplugins_loaded', array( 'WPSE113391Parenti18nLoader', 'getInstance' ) );
class WPSE113391Parenti18nLoader
{
public static $instance = null;
private $theme = null;
public static function getInstance()
{
null === self::$instance AND self::$instance = new self;
return self::$instance;
}
public function __construct()
{
add_action( 'after_setup_theme', array( $this, 'i18nAutoloader' ), 20 );
}
public function setTheme( $theme )
{
return $this->theme = $theme;
}
public function getTheme()
{
return $this->theme;
}
public function i18nAutoloader()
{
if ( ! is_child_theme() )
return;
$current_theme = wp_get_theme();
if ( '' === $current_theme->parent()->get( 'DomainPath' ) )
{
$this->setTheme( $current_theme->parent() );
add_filter( 'override_load_textdomain', array( $this, 'overrideI18nLoader' ), 10, 3 );
}
$current_theme->parent()->load_textdomain();
}
public function overrideI18nLoader( $activate, $domain, $mofile )
{
// Don't intercept anything else: Self removing
remove_filter( current_filter(), __FUNCTION__ );
// Rebuild the internals of WP_Theme::get_stylesheet_directory() and load_theme_textdomain()
$theme = $this->getTheme();
$path = trailingslashit( $theme->get_theme_root() ).$theme->get_template();
$locale = apply_filters( 'theme_locale', get_locale(), $domain );
load_textdomain( $domain, "{$path}/{$locale}.mo" );
// Return true to abort further attempts
return true;
}
}
次佳解決方案
預設情況下,這只是開箱即用。如果父主題提供翻譯,child-theme 將會結束。
如果它不工作的東西是錯誤的。這是在我的情況,這裡是我做了 trouble-shoot:
-
我啟用了父主題,看看翻譯是否在那裡工作 – 沒有。
-
然後我安裝了 Debug Translations 外掛來瞭解哪些語言檔案被載入。
-
然後,我啟動了一個 Xdebug 除錯會話 (
?XDEBUG_SESSION_START=1),並透過在其中放置一個斷點來驗證報告已被破壞的載入位置。
然後,結果是 Wordpress 正在尋找一個不同的 file-name 。我更正了檔名,然後工作。
故事計程車氣:主題中的語言檔案應該只用本地命名,就像我的情況下的 de_DE.mo 。
故障:
+ wp-content
+--+ themes
| +--+ child-theme
| | `--- style.css
. . ...
| `--+ twentytwelve
| +--+ languages
| | `--- twentytwelve-de_DE.mo <<<
. ...
加工:
+ wp-content
+--+ themes
| +--+ child-theme
| | `--- style.css
. . ...
| `--+ twentytwelve
| +--+ languages
| | `--- de_DE.mo <<<
. ...
參考文獻
注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。