web-dev-qa-db-ja.com

ページ編集画面でページテンプレートのドロップダウンにアイテムを追加する

私はMVCアプローチでWPテーマを開発しています。親ディレクトリにはindex.phpfunctions.phpおよびstyles.cssのみがあります。そのため、ページテンプレートを配置したくはありません。編集画面の機能は変わりませんが、プログラムでViewクラスからテンプレートを提供したいのです。

ユーザーは編集画面でページテンプレートを選択するオプションを持つ必要があります。アイテムをテンプレートドロップダウンに追加するにはどうすればよいですか。

theme_page_templates filterにフックしようとしました。

サンプルコード:

add_filter( 'theme_page_templates', function($templates){

    $templates['my-page-template.php'] = "My Page Template";

    return $templates;

});

これは、追加されたページテンプレートアイテムを削除するフィルタを適用した配列で array_intersect_assoc() を使用するため、機能しません。この機能が使用される理由がわかりません。リストからページテンプレートを削除することしかできませんが、指定されたフィルタを使用して新しいテンプレートを追加することはできません。

他に何かありますか?

4
Sisir

私はあなたに別のアプローチを提供すると思いました。これも少し厄介ですが、これは一般的な目的であり、使用するファイル名とラベルを簡単に登録することができます。

if ( class_exists( 'WPSE_196995_Page_Templates' ) ) {   
    WPSE_196995_Page_Templates::register_page_template(
        'My Page Template',
        'my-page-template.php'
    );
}

あなたのテーマのfunctions.phpファイルに上記のコードを追加することができます。

上記が実際に機能するようにするために、プラグインとして使用することも、単にfunctions.phpにコピーすることもできる自己完結型クラスを実装しました。

<?php   
/**
 * Plugin Name: WPSE 196995 Page Templates
 *
 * Class WPSE_196995_Page_Templates
 *
 * Allows registering page templates via code.
 */
class WPSE_196995_Page_Templates {

    static $registered_templates = array();

    static function on_load() {

        /**
         * Add registered page templates to 'page_template' cache.
         * @note This hook is called just before page templates are loaded
         */
        add_action( 'default_page_template_title', array( __CLASS__, '_default_page_template_title' ) );
    }

    /**
     * Register page templates
     *
     * @param string $label
     * @param string $filename
     */
    static function register_page_template( $label, $filename ) {

        self::$registered_templates[ $filename ] = $label;

    }

    /**
     * Add registered page templates to 'page_template' cache.
     *
     * @param string $title
     *
     * @return string mixed
     */
    static function _default_page_template_title( $title ) {

        /**
         * @var WP_Theme $theme
         */
        $theme = wp_get_theme();

        /**
         * Access the cache the hard way since WP_Theme makes almost everything private
         */
        $cache_hash = md5( $theme->get_stylesheet_directory() );

        /**
         * Get the page templates as the 'page_templates' cache will already be primed
         */
        $page_templates = wp_cache_get( $key = "page_templates-{$cache_hash}", $group = 'themes' );

        /**
         * Add in registered page templates
         */
        $page_templates += self::$registered_templates;

        /**
         * Now update the cache, which is what the get_page_templates() uses.
         */
        wp_cache_set( $key, $page_templates, $group, 1800 );

        /**
         * We are using this hook as if it were an action.
         * So do not modify $title, just return it.
         */
        return $title;

    }

}
WPSE_196995_Page_Templates::on_load();

このクラスはもちろんregister_page_template()メソッドを提供しますが、実際にページテンプレートを追加するために、オブジェクトキャッシュに設定されている'page_templates'の値を更新します。

WordPressがWP_Themeクラスprivateのほとんどのメソッドとプロパティを作成したため、少し厄介ですが、幸運にもそれらは値を格納するために公にアクセス可能なWordPressオブジェクトキャッシュを使用しました。そして、ページテンプレートドロップダウンが生成されてブラウザに送信される直前に呼び出される'default_page_template_title'フックのオブジェクトキャッシュを更新することによって、あなたが望むようにWordPressにあなたのページテンプレートを表示させることができます。

5
MikeSchinkel

醜いハックで回った: - /。後でjQueryを使用する場合は、回答を更新します。解決策はまだテンプレートファイルが必要ですが、テンプレートファイルのコードはindex.phpからロードします

  1. 私は新しいtemplate/ディレクトリを作り、そこにすべてのページテンプレートを置きました。
  2. すべてのページテンプレートは空白です。ドロップダウンに表示されるのはそれらだけです。
  3. template_includeフィルタを使ってindex.phpにリダイレクトする

コード

空白のページテンプレートの例

<?php
/*
Template Name: No Sidebar
 *
 * */

フィルタ

add_filter( 'template_include', function ($template ) {

    if ( !is_page_template()  )
        return $template;

    return locate_template( array( 'index.php' ), true );

}, 99);

私はTracチケットを作成しました フィルタを介してテンプレートを追加できるようにします。

1
Sisir