web-dev-qa-db-ja.com

独自の.phpファイルを使用せずにカスタムページテンプレートを定義する

テンプレート名を宣言するためのページ上部のコメントを含む.phpファイルを持たずに、何らかの関数/ filter/hookからページテンプレートを定義する方法はありますか?


たとえば、これを行う代わりに、

some-custom-page-template.php

/**
* Template Name: Some Custom Page Template
*/

another-custom-page-template.php

/**
* Template Name: Another Custom Page Template
*/

こんなことができるのかな。

functions.php

wp_some_function_to_define_templates( 'Some Custom Page Template' );
wp_some_function_to_define_templates( 'Another Custom Page Template' );

EDIT:私は複素数と種類の{実験的 WPテーマを書いています - それはオブジェクトの通りです - WPにすることで、各ページに何を表示するかを決定するControllerクラス、DBからデータを取得するDAOクラス、ビューを生成するTwigテンプレートなどがあります。

私は自分のページテンプレートがちょうど私がなんらかのControllerを呼び出してそれが仕事をすることを可能にするコードの行になったので、Twigテンプレートを最終的にレンダリングしました。それで私はその呼び出しをControllerへ、template_includeフィルターの内側へ移動することに決めました、それで私はPage Templatesにどんなコードも置く必要さえありません...

私はページテンプレートを削除するかもしれませんが、それらのためにいくつかのアドバンストカスタムフィールドグループを設定するために、どういうわけかgroupページにそれらをまだ必要としています...

それで、私は最終的にいくつかのテンプレート名でトップにコメントだけを含む約15のPHPファイルで終わりました。

私は車輪を再発明しようとしていますか?ある意味ではあるかもしれませんが、それは本当にかっこいいテーマになりつつあると思います。

6
MikO

WordPressはファイルヘッダーからテンプレートを読み込み、それらをキャッシュに設定します。 using wp_cache_set() md5のスタイルシートフォルダから派生したキーを使用します。

そのキャッシュをオーバーライドするだけで、必要なテンプレートを表示できます。そのキャッシュを上書きするためには、同じキーを使用してwp_cache_set()を再度呼び出す必要があります。

まず最初に、表示したいテンプレートを取得する関数を書きましょう。テンプレートを設定する方法はたくさんあります。オプション、設定ファイル、フィルタ、またはそれらの組み合わせです。

function get_custom_page_templates() {
  $templates = array();
  // maybe by options? --> $templates = get_option( 'custom_page_templates' );
  // maybe by conf file? --> $templates = include 'custom_page_templates.php';
  return apply_filters( 'custom_page_templates', $templates );
}

その後、WordPressがキャッシュを保存した直後に、ページ編集内のテンプレートを取得する必要があります。さらに、保存できるように編集フォームが投稿されたときに再度取得する必要があります。

最初のスコープに'edit_form_after_editor'フックを、2番目のスコープに'load-post.php''load-post.new'を使うことができます。

add_action( 'edit_form_after_editor', 'custom_page_templates_init' );
add_action( 'load-post.php', 'custom_page_templates_init_post' );
add_action( 'load-post-new.php', 'custom_page_templates_init_post' );

function custom_page_templates_init() {
  remove_action( current_filter(), __FUNCTION__ );
  if ( is_admin() && get_current_screen()->post_type === 'page' ) {
    $templates = get_custom_page_templates(); // the function above
    if ( ! empty( $templates ) )  {
      set_custom_page_templates( $templates );
    }
  }
}

function custom_page_templates_init_post() {
  remove_action( current_filter(), __FUNCTION__ );
  $method = filter_input( INPUT_SERVER, 'REQUEST_METHOD', FILTER_SANITIZE_STRING );
  if ( empty( $method ) || strtoupper( $method ) !== 'POST' ) return;
  if ( get_current_screen()->post_type === 'page' ) {
    custom_page_templates_init();
  }
}

最後にしなければならないことは、キャッシュを編集してテンプレートを含めるset_custom_page_templates()関数を作成することです。ファイルヘッダーで定義されたテンプレートは必ずマージしてください。

function set_custom_page_templates( $templates = array() ) {
  if ( ! is_array( $templates ) || empty( $templates ) ) return;
  $core = array_flip( (array) get_page_templates() ); // templates defined by file
  $data = array_filter( array_merge( $core, $templates ) );
  ksort( $data );
  $stylesheet = get_stylesheet();
  $hash = md5( get_theme_root( $stylesheet ) . '/' . $stylesheet );
  $persistently = apply_filters( 'wp_cache_themes_persistently', false, 'WP_Theme' );
  $exp = is_int( $persistently ) ? $persistently : 1800;
  wp_cache_set( 'page_templates-' . $hash, $data, 'themes', $exp );
}

このコードを実行することで、get_custom_page_templates()関数で使用した方法を使用してカスタムテンプレートを設定できます。ここではフィルタを使用します。

add_filter( 'custom_page_templates', function( $now_templates ) {

  $templates = array(
    'some-custom-page-template' => 'Some Custom Page Template',
    'another-custom-page-template' => 'Another Custom Page Template' ,
  );

  return array_merge( $now_templates, $templates );

} );

そして、これで終わりです。

6
gmazzap

私があなたを理解しているならば、あなたは template_include フックでこれをすることができます。例えば:

add_filter( 'template_include', 'phpless_template');
function phpless_template( $template ) {  
  get_header();
  // some php
  get_footer();
  die;
}
2
s_ha_dum

より簡単な回避策をお勧めします。

  1. あなたのconfiguration/functions/indexファイルにconfig変数$config_template = false;(*)を定義してください。
  2. "include"フォルダを作成します(おそらくあなたはすでにそれを持っています)
  3. ファイルsome-custom-page-template.phpとanother-custom-page-template.phpをそこに置きます。
  4. これらのファイルでは、単純に$ config_templateに値を割り当ててから、ループをレンダリングするために使用しているページが必要になります。例えば、$config_template = 'some-custom-page'; require( "../index.php" );
  5. このファイル(index.php)には、$ config_templateの値に基づいて欲しいことができます。

この方法を使用すると、WPの通常のワークフローが強制されるわけではありません(これは決して良い考えではありません)が、プロジェクトを十分にクリーンに保ちます。

(*)おそらくあなたはすでにあなたの設定を管理するために何らかのオブジェクトプロパティを使っています。そこに$ config_template変数を置きます。

0
Marco Panichi