问题描述
只要创建一个 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 文件以正确挂钩的默认优先级正确加载。 -
然后它检索
instanceof
WP_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
extend
theWP_Theme
class 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 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。