問題描述

我最喜歡的部分 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 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。