问题描述

我最喜欢的部分 Wordpress template hierarchy 是能够快速创建模板文件的页面通过 slug,而无需编辑 WordPress 中的页面选择一个模板。

我们目前可以这样做:

page-{slug}.php

但我希望能够做到这一点:

single-{post_type}-{slug}.php

所以,例如,在一个名为 review 的帖子中,我可以在 single-review-my-great-review.php 上为 「我的好评」 发表一个模板

有没有人设定这个? single-{post_type}-{slug}.php

最佳解决方案

A) 核心的基础

您可以看到 in the Codex 模板层次结构说明,single-{$post_type}.php 已被支持。


B) 扩展核心层次结构

现在/wp-includes/template-loader.php 里面有一些过滤器和钩子。

  • do_action('template_redirect');

  • apply_filters( 'template_include', $template )

  • AND:get_query_template( $type, ... )中的特定过滤器命名为"$type}_template"

B.1) 工作原理

  1. 在模板加载程序文件中,模板通过查询 var /wp_query 条件:is_*()加载。

  2. 条件然后触发 (在”single” 模板的情况下):is_single() && $template = get_single_template()

  3. 这样触发 get_query_template( $type, $templates ),其中 $typesingle

  4. 然后我们有"{$type}_template"过滤器


C) 解决方案

由于我们只想在实际的"single-{$object->post_type}.php"模板之前加载一个模板来扩展层次结构,所以我们将拦截层次结构,并将一个新模板添加到模板数组的开头。

// Extend the hierarchy
function add_posttype_slug_template( $templates )
{

    $object = get_queried_object();

    // New
    $templates[] = "single-{$object->post_type}-{$object->post_name}.php";
    // Like in core
    $templates[] = "single-{$object->post_type}.php";
    $templates[] = "single.php";

    return locate_template( $templates );
}
// Now we add the filter to the appropriate hook
function intercept_template_hierarchy()
{
    add_filter( 'single_template', 'add_posttype_slug_template', 10, 1 );
}
add_action( 'template_redirect', 'intercept_template_hierarchy', 20 );

注意:(如果要使用除默认对象块之外的其他东西),您必须根据您的 permalink-structure 调整 $slug 。只需使用全球 (object) $post 所需的任何东西。

Trac 门票

由于上述方法目前不受支持 (您只能以这种方式过滤绝对定位的路径),以下是 trac 门票列表:

次佳解决方案

按照 Template Hierarchy image,我看不到这样的选择。

所以我会如何去做

解决方案 1(在我看来最好)

制作一个模板文件并将其与审阅相关联

 <?php
 /*
 Template Name: My Great Review
 */
 ?>

在您的主题目录中添加模板 php 文件,它将在帖子的编辑页面中显示为模板选项。

解决方案 2

这可能是使用 template_redirect 钩子来实现的。

在 functions.php 文件中:

 function my_redirect()
 {
      global $post;

      if( get_post_type( $post ) == "my_cpt" && is_single() )
      {
           if( file_exists( get_template_directory() . '/single-my_cpt-' . $post->post_name . '.php' ) )
           {
                include( get_template_directory() . '/single-my_cpt-' . $post->post_name . '.php' );
                exit;
           }
      }
 }
 add_action( 'template_redirect', 'my_redirect' );

编辑

添加了 file_exists 检查

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。