web-dev-qa-db-ja.com

ページテンプレートをカスタムフォルダに移動する方法

たとえば、page-contact.phppage-gallery.phpなどのページスラッグ、またはpage-2.phppage-11.phpなどのページIDを使用するページテンプレートを作成しました。

これらのテンプレートを/mytheme/pages/などのサブフォルダに移動するにはどうすればよいですか。

5
Den

/ YOUR_THEME/page-templates /は、admin-ページ編集画面で割り当てられたカスタムページテンプレートに対してのみ機能し、page- $ slugまたはpage- $ idという名前のテンプレートに対しては機能しません。

私のビューの正しいフィルタフックはpage_templateですが、あなたのページに他の可能なテンプレートを捨てたくはありません。 /my-sub-dir/page-$slug.phpテンプレートファイルを作成しませんでした。

WPが標準テンプレート階層を使用してページのテンプレートを見つけた直後に、page_templateフィルタフックが呼び出されます。追加のテンプレートをテンプレート階層の右側に挿入できるようにするフィルタがあると便利ですが、それがない場合は、WordPressのget_page_template()関数からページテンプレートの検索を複製する必要があります。 /wp-includes/template.phpにあります。

function get_page_template() {
    $id = get_queried_object_id();
    $template = get_page_template_slug();
    $pagename = get_query_var('pagename');

    if ( ! $pagename && $id ) {
        // If a static page is set as the front page, $pagename will not be set. Retrieve it from the queried object
        $post = get_queried_object();
        if ( $post )
            $pagename = $post->post_name;
    }

    $templates = array();
    if ( $template && 0 === validate_file( $template ) )
        $templates[] = $template;
    if ( $pagename )
        $templates[] = "page-$pagename.php";
    if ( $id )
        $templates[] = "page-$id.php";
    $templates[] = 'page.php';

    return get_query_template( 'page', $templates );
}

この関数はPagesのための可能なテンプレートの配列を構築します。 get_query_template()は次にlocate_template()を使用して配列を調べ、最初に見つかったテンプレートのファイル名を返します。

私たちは提案されたテンプレートのリストに引っ掛かることができないので、残念ながら私たちはこの仕事のいくつかを複製しなければならないでしょう。

これが私たち自身の機能です:

function tbdn_get_page_template() {
    $id = get_queried_object_id();
    $template = get_page_template_slug();
    $pagename = get_query_var('pagename');

    if ( ! $pagename && $id ) {
        // If a static page is set as the front page, $pagename will not be set. Retrieve it from the queried object
        $post = get_queried_object();
        if ( $post )
            $pagename = $post->post_name;
    }

    $templates = array();

    if ( $template && 0 === validate_file( $template ) )
        $templates[] = $template;
    // if there's a custom template then still give that priority

    if ( $pagename )
        $templates[] = "our-sub-dir/page-$pagename.php";
    // change the default search for the page-$slug template to use our directory
    // you could also look in the theme root directory either before or after this

    if ( $id )
        $templates[] = "our-sub-dir/page-$id.php";
    $templates[] = 'page.php';

    /* Don't call get_query_template again!!!
       // return get_query_template( 'page', $templates );
       We also reproduce the key code of get_query_template() - we don't want to call it or we'll get stuck in a loop .
       We can remove lines of code that we know won't apply for pages, leaving us with...
    */

    $template = locate_template( $templates );

    return $template;
}

add_filter( 'page_template', 'tbdn_get_page_template' );

警告:

1 - 私はこれをテストしていませんが、テンプレートの階層構造をいじっているのであれば、必ずWPからコピーされたコードをたどって従うことができます。

2 - 将来のコアコードがページのテンプレート階層を変更した場合、上記のコードは古くなります。

4

私は この答えに で詳細を投稿しました。ここでは、コードはこの質問の2つの特定の違いに基づいて調整されます。

  1. フォールバックせずにページテンプレートをサブディレクトリに移動します。例えば、それはTHEME/sub-directory/page-{slug}.phpをチェックしますが、それはnotcheck THEME/page-{slug}.phpです、なぜならOPが尋ねたものです。しかし、他の答えのフォールバックのオプションは、特に子テーマの場合には、より良いです。親テーマはフォールバックに依存するかもしれません)。

  2. page-{slug}.phppage-{id}.phpの両方をサブディレクトリに移動します。


使用するフィルタフック:

/THEME/page-templates/のように、ページテンプレートをサブディレクトリに移動する最善の方法は、page_template_hierarchyfilterフック)を使用することです。

注:元のフィルタフックは{$ type} _template_hierarchyです。これはpage_template_hierarchypageの場合は$typeになります。

サンプルコード

<?php
/*
Plugin Name:  WPSE Page Template move to Sub Directory
Plugin URI:   https://wordpress.stackexchange.com/a/227006/110572
Description:  WPSE Page Template move 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 wpse227006_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;
    $cnt = count( $templates );
    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;
    }

    // the last one in $templates is page.php, so
    // all but the last one in $templates starting from $page_tpl_idx will be moved to sub-directory
    for( $i = $page_tpl_idx; $i < $cnt - 1; $i++ ) {
        $templates[$i] = WPSE_PAGE_TEMPLATE_SUB_DIR . '/' . $templates[$i];
    }

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

WordPressは/ YOUR_THEME/page-templates /のテンプレートファイルを認識します: https://developer.wordpress.org/themes/basics/organizing-theme-files/#page-templates-folder

0