如何将Page-{slug}.php这样的页面模板文件移到子目录中?

时间:2018-08-22 作者:manifestor

我想移动页面模板文件,如page-{slug}.php 到我的主题中的子目录,WordPress将自动识别它们。如果所述表单的页面模板在子目录中不存在,那么WordPress应该回到默认的模板加载规则。我如何才能做到这一点?

Note-1: This 对于页面模板和this 链接提及template-parts/page, 这不是一回事。

Note-2: 我有多个page-{slug}.php 像页面模板文件一样,我想将它们移动到子目录中,以获得更整洁的文件组织。

1 个回复
最合适的回答,由SO网友:Fayaz 整理而成

如何加载页面模板:根据默认设置WordPress Template Hierarchy, 一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.phpsingular.php 和index.phpnot 实际上是页面模板。singular.php 是任何单一帖子类型的回退模板,以及index.php 是WordPress模板应该加载的任何内容的最终回退模板。所以前五个是页面模板。

    如何从层次结构中的子目录插入模板文件:

    WordPress核心函数get_page_template() 生成必要的page 模板层次结构数组,就在决定从层次结构加载哪个模板文件之前,WordPress激发page_template_hierarchy 过滤器挂钩。因此,添加子目录的最佳方法是WordPress将在其中查找page-{slug}.php 自动模板是使用此过滤器并在页面模板层次结构数组中插入相对于该子目录的正确文件名。

    Note:原始过滤器挂钩是一个动态过滤器挂钩,定义为{$type}_template_hierarchy, 位于wp-includes/template.php 文件所以当$typepage, 过滤器挂钩变为page_template_hierarchy.

    现在,出于我们的目的,我们将注入sub-directory/page-{slug}.php 前一个文件名page-{slug}.php 在传递给hooks回调函数的模板层次结构数组中。这样,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

      1. 样品functions.php 代码:

        如果计划仅对单个主题进行此更改,则可以在活动主题的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 文件中,您将需要使用相同的示例代码创建一个简单的插件。

使用文件名保存以下代码,例如。page-slug-template-subdir.php 在WordPress中plugins 目录:

<?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\' );
使用上述任一代码,WordPress将识别page-{slug}.php 中的模板文件page-templates 自动创建主题的目录。

比如说,你有一个about 页所以,如果它没有custom page template 从编辑器中设置,然后WordPress将查找THEME/page-templates/page-about.php 模板文件,如果不存在,WordPress将查找THEME/page-about.php 模板文件等(即默认页面模板层次结构)。

结束

相关推荐

是否覆盖子主题中的GET_TEMPLATE_DIRECTORY()?

是否可以更换get_template_directory() 在我孩子的功能中。php文件?我要更改文件:/** * Load Custom Post types file. */ require get_template_directory() . \'/inc/post-types.php\'; 很明显,我希望在更新主题时不要覆盖我的作品,那么我可以取消注册父文件,然后在我孩子的函数文件中重新注册我孩子的文件吗?