web-dev-qa-db-ja.com

子テーマ関数から親テーマに含まれるクラスのインスタンスを宣言する

これはすべて「うまくいく」ことに注意してください - 問題はベストプラクティスであり、正しく機能するために2つの場所にクラスを含むPHPファイルを含める必要がある理由を試してみることです。

私は自分自身の開発サイクルをスピードアップするために単純な親テーマに取り組んでいます - そして単純な子テーマをテストすることになりました。

私は、子のfunctions.phpファイルが親のfunctions.phpの前に呼び出されることを理解しています - それはすべてのPHP関数とCPTを追加するためのクラスを含みます。

私は子テーマからCPTを構築したいのですが - 私は親がすべての再利用可能で更新可能な機能を含むことを望みます - しかしそれが使用される各WPインストールに追加機能をあらかじめ構築しません。

コードの質問に:

私はそのクラス(別のPHPファイルにある)を子のfunctions.phpに含めてからインスタンスをインスタンス化しようとしました。例えば:

require_once TEMPLATEPATH."/library/cpt/cpt.php"; // CPT class ##
$cpt_tree = new Custom_Post_Type( "tree" ); // New CPT - "tree" ##

ページを再読み込みするとエラーが発生します。

Fatal error: Class 'Custom_Post_Type' not found in C:\xampp\htdocs\site\wordpress\wp-content\themes\child\functions.php on line 14

そのため、同じPHPファイルを親のfunctions.phpファイルに含めましたが、すべてうまくいきました。実験として、子テーマからクラスを削除したところ、同じエラーが発生しました。

この質問には多くのコード例が欠けていることを知っています - 誰かと鐘を鳴らすことを望みます - あるいはClassesの使用についてもっと理解できる誰かが私にいくつかのポインタを与えることができるでしょう - functions.phpファイルはできるだけきれいにしておきたいです。

5
Q Studio

親テーマにロードされているすべてのクラスを予測可能なアクション(特定時点)で処理し、後で子テーマにフックします。

例:

add_action( 'wp_loaded', 'parent_prefix_load_classes', 10 );

function parent_prefix_load_classes()
{
    $classes = [ 'Extra_Comment_Walker', 'Extra_Nav_Menu_Walker' ];

    foreach ( $classes as $class )
    {
        locate_template( "php/class.$class.php", TRUE, TRUE );
    }
}

子テーマにインスタンスを作成することで、クラスがロードされた後にコードが実行されることを確認します。

// Priority 11 to run after the parent theme's loader.
add_action( 'wp_loaded', 'child_prefix_create_objects', 11 );

function child_prefix_create_objects()
{
    $nav_walker = new Extra_Nav_Menu_Walker;
}

経験則:

  • ファイル(function.php)が呼び出されたときだけに何も読み込まないwp_loadedを待ちます。
  • 実行順序を制御するには、priority引数を使用します。

いくつかのメモ:

  • カスタム投稿タイプ、分類法、およびショートコードはプラグインに属します。それらはテーマの一部になるべきではありません、それはユーザーにとってロックイン効果を生み出すでしょうから。テーマの切り替えによってコンテンツが破損する場合は、何か問題がありました。
  • テーマにrequire_onceを使用しないでください。 locate_template() はもっと柔軟です。同じディレクトリ構造を使用している場合は、子テーマでクラス全体を上書きすることができます。
5
fuxia