web-dev-qa-db-ja.com

プログラムでカスタムテンプレートページを追加する

私はプラグインからテンプレートページを追加しようとしています、そして、私のテンプレートページはこのプラグインフォルダの中にあります。

 global $user_ID;
    $new_post = array(
        'post_title' => 'Test Template Page',
        'post_content' => 'Some text',
        'post_status' => 'publish',
        'post_date' => date('Y-m-d H:i:s'),
        'post_author' => $user_ID,
        'post_type' => 'page',
        'post_category' => array(0)
    );
    $post_id = wp_insert_post($new_post);
    if (!$post_id) {
        wp_die('Error creating template page');
    } else {
        update_post_meta($post_id, '_wp_page_template', 'tp-file.php');
    }

tp-file.phpが私のカスタムテンプレートページです。そのファイルをmy-themeフォルダに置いたとき、それはうまく機能しますが、pluginフォルダからのファイルでこれをしたいので、ユーザにそれをコピーさせる必要はありません。プラグインフォルダからテンプレートフォルダへのファイル。これは可能ですか。

6
user1147

リンクされた記事は正しい軌道に乗っています、しかし、私はあなたにとってそれをより簡単にします..;)

add_filter( 'page_template', 'catch_plugin_template' );

function catch_plugin_template( $template ) {
    if( 'tp-file.php' == basename( $template ) )
        $template = WP_PLUGIN_DIR . '/yourpluginname/tp-file.php';
    return $template;
}

フィルタは基本的にあなたの特別ページテンプレートが現在のページに設定されているかどうかを調べます。もしそうであれば、代わりにあなたのプラグインテンプレートを指すようにパスを更新します。

パスが正しいことを確認してください。そうしないと、インクルードエラーが発生します。

フォローアップ#1

最初の問題は、WordPressがテンプレートをページテンプレートとして検証することです。ファイルがテーマフォルダ内にあるかどうかを確認し、有効なテンプレートファイルであればチェックします。そうでない場合は、page.phpのように、より汎用的なテンプレートが含まれます。

しかし、これはmetaフィールドがまだあなたのカスタムテンプレートの値を保持しているという事実を変えません、そしてまたis_page_template( 'tp-file.php' )が私の前の条件ステートメントの代わりに使われたなら正しくtrueを返します、例えば。

// Filter page template
add_filter('page_template', 'catch_plugin_template');

// Page template filter callback
function catch_plugin_template($template) {
    // If tp-file.php is the set template
    if( is_page_template('tp-file.php') )
        // Update path(must be path, use WP_PLUGIN_DIR and not WP_PLUGIN_URL) 
        $template = WP_PLUGIN_DIR . '/tp-test/tp-file.php';
    // Return
    return $template;
}

注: WP_PLUGIN_DIR定数は paths ...には適していないため、WP_PLUGIN_URLを使用するようにコードを切り替えました(URLではなくパスを使用する必要があります)。

1つの問題、そしてこれは本当にあなたが解決することができるものではありません、ページを編集するとき、管理エリアからページを見るとき、テンプレートはアクティブなテンプレートとしてリストされません。アクティブなテンプレートできることはたくさんあります。ページテンプレートのドロップダウンはテーマファイルをスキャンする関数から生成されます。プラグインテンプレートでリストを拡張できるようにするためのフックはありません。

個人的に私が 提案 したのは、回避策として、あなたの特別なプラグインページを使って作成されたすべてのページに追加のメタフィールドを保存し、save_postまたはwp_insert_post_dataにフックを追加してfieldが存在する場合は、ページテンプレートがtp-file.phpに設定されていることも確認し、存在しない場合はtp-file.phpに更新します。追加のメタフィールドは、どのページにプラグインテンプレートを添付する必要があるかを示すための、いわば単なるフラグです。

これがあなたのプラグインが最も基本的な形式で動作しているのです(はい、私はテストしました)... :)

<?php
/*
  Plugin Name: TP Test Plugin
  Plugin URI: 
  Description: TP Test Plugin
  Version: 1.0.0
  Author: 
  Author URI: 
*/

global $wp_version;

if( version_compare( $wp_version, "2.9", "<" ) )
    exit( 'This plugin requires WordPress 2.9 or newer. <a href="http://codex.wordpress.org/Upgrading_WordPress">Please update!</a>' );

// Add callback to admin menu
add_action('admin_menu', 'create_tp_menu');

// Callback to add menu items
function create_tp_menu() {
    add_management_page('TP Test', 'TP Test', 'manage_options', 'tp-teste', 'wp_tp_test_fnc' );
}

function wp_tp_test_fnc() {

    //include('tp-form-file.php');

    if( !empty( $_POST['tp_name'] ) ) {
        $tp_name = $_POST['tp_name'];

        global $user_ID;
        $new_post = array(
            'post_title' => $tp_name,
            'post_content' => 'Some text',
            'post_status' => 'publish',
            'post_date' => date('Y-m-d H:i:s'),
            'post_author' => $user_ID,
            'post_type' => 'page',
        );
        $post_id = wp_insert_post($new_post);

        if( !$post_id )
            wp_die('Error creating template page');
        else
            update_post_meta( $post_id, '_wp_page_template', 'tp-file.php' );
        /*
        $pt = get_page_templates();

        $pt['TP file test'] = WP_PLUGIN_URL . '/tp-test/tp-file.php';

        echo "<pre>";
        print_r($pt);
        echo "</pre>";
        */
    }   
    ?>
    <fieldset style="margin: 50px 100px;background-color: #cccccc;padding: 30px;border: 1px solid #ccc">
         <legend style="background-color: #ccccff;padding: 20px;font-weight: bold;font-size: 18px">Create Template Page</legend>
         <form name="frm_main" action="" method="POSt">
              <input class="text" type="text" name="tp_name" size="50" />
              <br />
              <input class="button" type="submit" value="Create Template Page" name="btn_submit" />
         </form>
    </fieldset>
    <?php

}


// Filter page template
add_filter('page_template', 'catch_plugin_template');

// Page template filter callback
function catch_plugin_template($template) {
    // If tp-file.php is the set template
    if( is_page_template('tp-file.php') )
        // Update path(must be path, use WP_PLUGIN_DIR and not WP_PLUGIN_URL) 
        $template = WP_PLUGIN_DIR . '/tp-test/tp-file.php';
    // Return
    return $template;
}

それが物事を整理するのに役立ちます願っています.. :)

9
t31os

page_templateフィルタは現在非推奨です。 ( http://adambrown.info/p/wp_hooks/hook/page_template

代わりにsingle_template(またはアーカイブテンプレートの場合はarchive_template)を試してください。

@ t31osの回答に基づく:

// Filter page template
add_filter('single_template', 'catch_plugin_template');

// Page template filter callback
function catch_plugin_template($template) {
    // If tp-file.php is the set template
    if( is_page_template('tp-file.php') )
        // Update path(must be path, use WP_PLUGIN_DIR and not WP_PLUGIN_URL) 
        $template = WP_PLUGIN_DIR . '/tp-test/tp-file.php';
    // Return
    return $template;
}
2
docker