問題描述
只要創建一個 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 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。