web-dev-qa-db-ja.com

Page- {slug} .phpのようなページテンプレートファイルをサブディレクトリに移動するにはどうすればいいですか?

WordPressが自動的にそれらを認識するように、page-{slug}.phpのようなページテンプレートファイルを私のテーマの中のサブディレクトリに移動したいです。当該フォームのページテンプレートがサブディレクトリ内に存在しない場合、WordPressはデフォルトのテンプレートロードルールにフォールバックします。どうすればそれを達成できますか?

Note-1: this の質問とそれに対応する回答はページテンプレートではより一般的で、 this リンクはtemplate-parts/pageと書いていますが、これは同じことではありません。

注2: 私は複数のpage-{slug}.php風のページテンプレートファイルを持っているので、もっと整理したファイル構成のためにそれらをサブディレクトリに移動したい。

8
chevallier

ページテンプレートのロード方法:

デフォルトの WordPressテンプレート階層 に従って、pageリクエストは、以下に述べるように優先度と命名に基づいてテンプレートをロードします:

  1. Custom Page Template:ページエディターで定義されている場合。
  2. page-{slug}.php
  3. page-{url-encoded-slug}.php:マルチバイト文字のみ。
  4. page-{id}.php
  5. page.php
  6. singular.php
  7. index.php

これらのうち、singular.phpindex.phpは、実際にはページテンプレートですnotです。 singular.phpは、単一の投稿タイプのフォールバックテンプレートであり、index.phpは、WordPressテンプレートがロードされるはずのあらゆるものの究極のフォールバックテンプレートです。したがって、最初の5つはページテンプレートです。

階層内のサブディレクトリからテンプレートファイルを挿入する方法:

WordPressコア関数 get_page_template() は、必要なpageテンプレート階層配列を生成し、階層から読み込むテンプレートファイルを正確に決定する直前に、WordPressがpage_template_hierarchyフィルターフック。したがって、WordPressがpage-{slug}.phpテンプレートを自動的に検索するサブディレクトリを追加する最良の方法は、このフィルターを使用し、ページテンプレート階層配列内のそのサブディレクトリに関連する適切なファイル名を挿入することです。

注:元のフィルターフックは、{$type}_template_hierarchy、これはwp-includes/template.phpファイルにあります。したがって、$typepageの場合、フィルターフックはpage_template_hierarchyになります。

ここで、目的のために、フックコールバック関数に渡されるテンプレート階層配列内のsub-directory/page-{slug}.phpの直前にpage-{slug}.phpファイル名を挿入します。そうすれば、WordPressは、存在する場合はsub-directory/page-{slug}.phpファイルをロードします。それ以外の場合は、通常のページテンプレートロード階層に従います。もちろん、一貫性を維持するために、Custom Page Templateファイルに比べてsub-directory/page-{slug}.phpに高い優先度を与えます。したがって、変更されたページテンプレート階層は次のようになります。

  1. Custom Page Template:ページエディターで定義されている場合。
  2. sub-directory/page-{slug}.php
  3. sub-directory/page-{url-encoded-slug}.php:マルチバイト文字のみ。
  4. page-{slug}.php
  5. page-{url-encoded-slug}.php:マルチバイト文字のみ。
  6. page-{id}.php
  7. page.php

サンプルfunctions.php CODE:

単一のテーマでのみこの変更を行う予定の場合、アクティブなテーマのfunctions.phpファイルで次のコードを使用できます。

// defining the sub-directory so that it can be easily accessed from elsewhere as well.
define( 'WPSE_PAGE_TEMPLATE_SUB_DIR', 'page-templates' );

function wpse312159_page_template_add_subdir( $templates = array() ) {
    // Generally this doesn't happen, unless another plugin / theme does modifications
    // of their own. In that case, it's better not to mess with it again with our code.
    if( empty( $templates ) || ! is_array( $templates ) || count( $templates ) < 3 )
        return $templates;

    $page_tpl_idx = 0;
    if( $templates[0] === get_page_template_slug() ) {
        // if there is custom template, then our page-{slug}.php template is at the next index 
        $page_tpl_idx = 1;
    }

    $page_tpls = array( WPSE_PAGE_TEMPLATE_SUB_DIR . '/' . $templates[$page_tpl_idx] );

    // As of WordPress 4.7, the URL decoded page-{$slug}.php template file is included in the
    // page template hierarchy just before the URL encoded page-{$slug}.php template file.
    // Also, WordPress always keeps the page id different from page slug. So page-{slug}.php will
    // always be different from page-{id}.php, even if you try to input the {id} as {slug}.
    // So this check will work for WordPress versions prior to 4.7 as well.
    if( $templates[$page_tpl_idx] === urldecode( $templates[$page_tpl_idx + 1] ) ) {
        $page_tpls[] = WPSE_PAGE_TEMPLATE_SUB_DIR . '/' . $templates[$page_tpl_idx + 1];
    }

    array_splice( $templates, $page_tpl_idx, 0, $page_tpls );

    return $templates;
}
add_filter( 'page_template_hierarchy', 'wpse312159_page_template_add_subdir' );

サンプルプラグイン:

複数のテーマで同じテンプレートファイルの構成を使用する場合は、この機能をテーマとは別にすることをお勧めします。その場合、上記のサンプルコードでテーマのfunctions.phpファイルを変更する代わりに、同じサンプルコードで簡単なプラグインを作成する必要があります。

次のコードをファイル名で保存します。 WordPress pluginsディレクトリ内のpage-slug-template-subdir.php

<?php
/*
Plugin Name:  WPSE Page Template page-slug.php to Sub Directory
Plugin URI:   https://wordpress.stackexchange.com/a/312159/110572
Description:  Page Template with page-{slug}.php to a Sub Directory
Version:      1.0.0
Author:       Fayaz Ahmed
Author URI:   https://www.fayazmiraz.com/
*/

// defining the sub-directory so that it can be easily accessed from elsewhere as well.
define( 'WPSE_PAGE_TEMPLATE_SUB_DIR', 'page-templates' );

function wpse312159_page_template_add_subdir( $templates = array() ) {
    // Generally this doesn't happen, unless another plugin / theme does modifications
    // of their own. In that case, it's better not to mess with it again with our code.
    if( empty( $templates ) || ! is_array( $templates ) || count( $templates ) < 3 )
        return $templates;

    $page_tpl_idx = 0;
    if( $templates[0] === get_page_template_slug() ) {
        // if there is custom template, then our page-{slug}.php template is at the next index 
        $page_tpl_idx = 1;
    }

    $page_tpls = array( WPSE_PAGE_TEMPLATE_SUB_DIR . '/' . $templates[$page_tpl_idx] );
                                                                                  uded in the
    // page template hierarchy just before the URL encoded page-{$slug}.php template file.
    // Also, WordPress always keeps the page id different from page slug. So page-{slug}.php will
    // always be different from page-{id}.php, even if you try to input the {id} as {slug}.
    // So this check will work for WordPress versions prior to 4.7 as well.
    if( $templates[$page_tpl_idx] === urldecode( $templates[$page_tpl_idx + 1] ) ) {
        $page_tpls[] = WPSE_PAGE_TEMPLATE_SUB_DIR . '/' . $templates[$page_tpl_idx + 1];
    }

    array_splice( $templates, $page_tpl_idx, 0, $page_tpls );

    return $templates;
}
// the original filter hook is {$type}_template_hierarchy,
// wihch is located in wp-includes/template.php file
add_filter( 'page_template_hierarchy', 'wpse312159_page_template_add_subdir' );

使用法:

上記のいずれかのCODEを使用すると、WordPressはテーマのpage-{slug}.phpディレクトリ内のpage-templatesテンプレートファイルを自動的に認識します。

たとえば、aboutページがあるとします。エディターからcustom page templateが設定されていない場合、WordPressはTHEME/page-templates/page-about.phpテンプレートファイルを探し、存在しない場合はWordPressはTHEME/page-about.phpテンプレートを探しますファイルなど(つまり、デフォルトのページテンプレート階層)。

10
Fayaz