web-dev-qa-db-ja.com

プラグインフォルダからのカスタム投稿タイプテンプレート?

私のカスタム投稿タイプをプラグインとして提供したいのです。そうすれば、人々は自分のテーマフォルダに触れることなくそれを使用することができます。しかし、single-movies.phpなどのカスタム投稿タイプのテンプレートはテーマフォルダにあります。プラグインのフォルダ内のsingle-movies.phpをチェックするためのWPを取得する方法はありますか?関数を ファイラー階層にフックする ?またはget_template_directory(); ?

55
nathanbweb

single_templateフィルタフックを使うことができます。

/* Filter the single_template with our custom function*/
add_filter('single_template', 'my_custom_template');

function my_custom_template($single) {

    global $post;

    /* Checks for single template by post type */
    if ( $post->post_type == 'POST TYPE NAME' ) {
        if ( file_exists( PLUGIN_PATH . '/Custom_File.php' ) ) {
            return PLUGIN_PATH . '/Custom_File.php';
        }
    }

    return $single;

}
87
Bainternet

更新された答え

よりクリーンで短いバージョン.

function load_movie_template($template) {
    global $post;

    if ($post->post_type == "movie" && $template !== locate_template(array("single-movie.php"))){
        /* This is a "movie" post 
         * AND a 'single movie template' is not found on 
         * theme or child theme directories, so load it 
         * from our plugin directory
         */
        return plugin_dir_path( __FILE__ ) . "single-movie.php";
    }

    return $template;
}

add_filter('single_template', 'load_movie_template');

古い答え

@Brainternet回答に、テーマフォルダ内のカスタム投稿タイプ固有のテンプレートのチェックを追加しました。

function load_cpt_template($template) {
    global $post;

    // Is this a "my-custom-post-type" post?
    if ($post->post_type == "my-custom-post-type"){

        //Your plugin path 
        $plugin_path = plugin_dir_path( __FILE__ );

        // The name of custom post type single template
        $template_name = 'single-my-custom-post-type.php';

        // A specific single template for my custom post type exists in theme folder? Or it also doesn't exist in my plugin?
        if($template === get_stylesheet_directory() . '/' . $template_name
            || !file_exists($plugin_path . $template_name)) {

            //Then return "single.php" or "single-my-custom-post-type.php" from theme directory.
            return $template;
        }

        // If not, return my plugin custom post type template.
        return $plugin_path . $template_name;
    }

    //This is not my custom post type, do nothing with $template
    return $template;
}
add_filter('single_template', 'load_cpt_template');

これで、プラグインユーザーが自分のテーマにテンプレートをコピーしてそれを上書きできるようになります。

この例では、テンプレートはプラグインとテーマの両方のルートディレクトリになければなりません。

18
campsjos

私があなたがこれのためにフィルタ方法を使用しているとき、それがそのようにフィルタを優先することが非常に重要であることを指摘したいと思います:

add_filter('single_template', 'my_custom_template', 99);

そうしないと、時々WPがこのフィルタの後で再チェックしようとします。このため、2時間ほど髪を引き抜いていました。

3
RBizzle

プラグインに使用しているより良い方法があります。

@ campsjos 言及 here として、ファイルの存在チェックの代わりに、テーマ上書きテンプレートファイルにチェックインするlocate_templateをチェックできます。これは非常に明白です。

function my_plugin_templates() {
    if (is_singular('movie')) {
        if (file_exists($this->template_dir . 'single-movie.php')) {
            return $this->template_dir . 'single-movie.php';
        }
    }
}

template_includeフィルターフックを使用して、上記のコードを読み込みます。

add_filter('template_include' , 'my_plugin_templates');
0
pixelngrain