web-dev-qa-db-ja.com

子テーマは自動的に親テーマから翻訳をロードしますか?

単に子テーマを作成するだけで十分ですか。つまり、最低限必要なstyle.css以外は追加せずに技術的に言えば、子テーマにも自動的に親テーマの翻訳が使用されるのです。

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
 */

twentytwelve というテーマは標準の言語翻訳ファイルを持っています。

もしそれが私のサイト上で自動的には起こらないのなら、足りない翻訳をトラブルシューティングするのにふさわしい場所は何でしょうか。

7
hakre

子テーマを作成するだけで十分ですか-最低限のstyle.css以外は何も追加せずに技術的に言ってみましょう-親テーマの翻訳を子テーマにも自動的に使用するには?

基本的に、答えはNO、... but ...オプションがあります:

Muプラグインを追加します。

この(MU-)Pluginはいくつかのことを行います:

  1. 優先度20でafter_setup_themeにフックします-親textdomain/i18n .moファイルが正しいフックのデフォルトの優先度で correct /にロードされると仮定します。
  2. 次に、instanceof the WP_Theme(この場合は子テーマ)を取得します。
  3. 次に、実際に is 使用中の子テーマがあるかどうかを確認します。
  4. これが当てはまる場合、親ファイルからテキストドメインをロードするだけです。

コアクラスは多くのチェックを行うため、実際には非常に簡単です。親テーマのWP_Themeの別のインスタンスを取得します。次に、$current_theme->get( 'TextDomain' );を使用して、TextDomainヘッダーが設定されているかどうかを確認します。したがって、ポイントは1つあります convention ゲームに:このプラグインは only 動作します。親がテーマは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();
}

ここで問題が発生します。コアによって提供されるデフォルト/標準のTwenty *テーマには、Domain Pathヘッダーエントリがありません(!)。そして、これは私たちがしなければならないことですfix即座に、 load_theme_textdomain() elseは親テーマフォルダにない翻訳ファイルを検索します

  • 最初に子テーマフォルダー:get_stylesheet_directory().WP_Theme::get( 'DomainPath' )、つまり(A)Domain Pathを設定する必要があることを意味します and の接頭辞が必要ですスラッシュ:/
  • 次に、子テーマフォルダー: `get_stylesheet_directory()。 '/ languages'。
  • 最後のWP_LANGUAGE_DIR.'/themes'ディレクトリにあります。

注:これは単に「下位互換性」のために修正されることのないバグだと思います。つまり、バグがあることを意味しますが、そこには開発者は既にそれを回避しているかもしれません。 :P

それから別の問題があります。 WP_Themeクラスメソッドload_textdomain()は、$pathload_theme_textdomain()に内部的に渡します。そして、このパラメーターは$this->get_stylesheet_directory()です。そして、このメソッドは$this->theme_root . '/' . $this->stylesheetを返します。したがって、この関数は実際に非常に良好に動作します but get_stylesheet_directory()(フィルター可能だったはずです)。今考えるかもしれない

「ちょっと!クラスimplements ArrayAccess!ですから、不足している配列キーDomain Path!を設定するだけです。」

間違ったすべてのクラスプロパティはprivateとマークされ、アクセスできません。

その後、あなたは考えるかもしれません

「単にextendWP_Themeクラスを使用して、set()メソッドを定義して、欠落しているヘッダーエントリを手動で設定できるのはなぜですか?」

間違ったクラス自体はfinalであり、拡張可能ではありません。

結果:コールチェーンの最後の関数であるload_theme_textdomain()が提供するものが残っています。これで、load_theme_textdomain()呼び出しをインターセプトして correct ファイルをロードする、より大きなプラグインができました。他の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;
    }
}
7
kaiser

デフォルトではこれはそのまま使用できます。親テーマが翻訳を提供している場合は、子テーマがそれを引き継ぎます。

うまくいかない場合は、何か問題があります。これは私の場合です、これが私がそれをトラブルシュートした方法です:

  1. 私は親のテーマをアクティブにして、翻訳がそこで機能しているかどうかを確認しました - そうではありませんでした。
  2. それから Debug Translations プラグインをインストールして、どの言語ファイルを読み込もうとしているかを調べました。
  3. 次にXdebugデバッグセッション(?XDEBUG_SESSION_START=1)を開始し、そこにブレークポイントを配置してそこに足を踏み入れることによって、破損と報告されたロード位置を検証しました。

その後、Wordpressは別のファイル名を探していました。私はファイル名を修正し、それからそれはうまくいった。

物語の士気:テーマ内の言語ファイルは、私の場合は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    <<<
.    ...
3
hakre