在開發(fā)WordPress主題的時(shí)候,我們經(jīng)常需要為文章設(shè)置單獨(dú)的模版,比如,一篇文章在視頻分類中,我們需要為這篇文章設(shè)置視頻播放模版,一篇文章在圖片中,我們需要為這篇文章設(shè)置圖片相冊模版。在 WordPress 中,有很多辦法可以給文章設(shè)置單獨(dú)的模版。
第一種辦法是使用自定義頁面模版,這種方法是在 WordPress 4.7 中開始提供的,示例代碼如下,把 post 添加到 Template Post Type: 中,即可在發(fā)布文章的時(shí)候,和頁面一樣選擇單獨(dú)的模版了。
<?php
/*
Template Name: Full-width layout
Template Post Type: post, page, event
*/
// 下面是頁面模版的代碼
這種辦法實(shí)現(xiàn)起來很簡單,但是用戶卻要在發(fā)布文章時(shí)選擇一下對應(yīng)的模版,多了一次操作。
另外一個(gè)辦法是使用文章格式,這種方法需要WordPress主題支持文章格式,用戶發(fā)布文章的時(shí)候選擇文章格式,在模版中,我們根據(jù)文章格式調(diào)用對應(yīng)的模版,關(guān)鍵代碼如下。
<?php get_template_part( 'content', get_post_format() ); ?>
這種辦法同樣需要在后臺(tái)多一種選擇,并且 WordPress 支持的文章格式有限,雖然可以添加自定是文章格式,卻增加了不少復(fù)雜度。
為分類文章設(shè)置基于分類目錄的文章模版
上面兩種實(shí)現(xiàn)方法都不是很理想,可不可以像分類模版那樣,直接在主題中添加一個(gè)類似 category-single.php 的分類模版的文件,實(shí)現(xiàn)用戶選擇了分類后,WordPress 自動(dòng)選擇對應(yīng)的文章模版來顯示內(nèi)容呢?
我們搜索了一番,發(fā)現(xiàn)實(shí)現(xiàn)方法非常簡單,具體代碼如下,把下面的代碼添加到主題中后,在主題中添加一個(gè) single-category-slug.php 的模版文件,即可實(shí)現(xiàn)我們上面的設(shè)想,如果沒有為子分類設(shè)置模版,會(huì)自動(dòng)使用父級(jí)分類的文章模版,如果也沒有為父級(jí)分類設(shè)置文章模版,則使用默認(rèn)的文章模版。
add_filter( 'single_template', function ( $template )
{
foreach ( (array) get_the_category() as $cat ) {
if ( file_exists( TEMPLATEPATH . "/single-category-{$cat->slug}.php" ) ) return TEMPLATEPATH . "/single-category-{$cat->slug}.php";
if ( $cat->parent ) {
$cat = get_the_category_by_ID( $cat->parent );
if ( file_exists( TEMPLATEPATH . "/single-category-{$cat->slug}.php" ) ) return TEMPLATEPATH . "/single-category-{$cat->slug}.php";
}
}
return $template;
} );
結(jié)合 Yoast SEO 的主分類功能指定分類文章模版
使用了一段時(shí)間之后,我們發(fā)現(xiàn),上面的代碼有一些小問題。如果一個(gè)文章同時(shí)設(shè)置了兩個(gè)分類,WordPress 會(huì)選擇第一個(gè)分類對應(yīng)的分類文章模版來顯示內(nèi)容,有時(shí)候,這不是我們想要的效果,我們需要讓文章按照我們指定的分類來選擇文章模版,聯(lián)想到 Yoast SEO 插件有一個(gè)設(shè)置文章主分類的功能,我們調(diào)整了一下上面的代碼,最終代碼如下。
add_filter( 'single_template', function ( $template )
{
// 獲取主分類
$primary_cat_id = get_post_meta( get_the_ID(), '_yoast_wpseo_primary_category', true );
foreach ( (array) get_the_category() as $cat ) {
// 嘗試使用主分類文章模版
if ( $primary_cat_id ) {
$primary_cat = get_term( $primary_cat_id );
if ( file_exists( TEMPLATEPATH . "/single-category-{$primary_cat->slug}.php" ) ) {
return TEMPLATEPATH . "/single-category-{$primary_cat->slug}.php";
}
}
// 如果主分類模版不存在,使用分類文章模版
if ( file_exists( TEMPLATEPATH . "/single-category-{$cat->slug}.php" ) ) {
return TEMPLATEPATH . "/single-category-{$cat->slug}.php";
}
if ( $cat->parent ) {
// 如果分類文章模版不存在,嘗試初擁主分類父級(jí)文章模版
if ( $primary_cat_id ) {
$primary_cat = get_term( $primary_cat_id );
if ( $primary_cat->parent ) {
$primary_cat_parent = get_term( $primary_cat->parent );
}
if ( file_exists( TEMPLATEPATH . "/single-category-{$primary_cat_parent->slug}.php" ) ) {
return TEMPLATEPATH . "/single-category-{$primary_cat_parent->slug}.php";
}
}
// 如果主分類父級(jí)文章模版也不存在,嘗試使用父級(jí)分類文章模版
$cat = get_term( $cat->parent );
if ( file_exists( TEMPLATEPATH . "/single-category-{$cat->slug}.php" ) ) {
return TEMPLATEPATH . "/single-category-{$cat->slug}.php";
}
}
}
return $template;
} );
Yoast SEO 會(huì)自動(dòng)設(shè)置第一個(gè)分類為主分類,并且大部分情況下,客戶都不會(huì)為一篇文章設(shè)置兩個(gè)不同的分類,所以發(fā)布文章的時(shí)候,需要調(diào)整主分類的操作其實(shí)很少。上面的代碼很好的實(shí)現(xiàn)了我們的需求,讓我們開發(fā)的定制主題可以自動(dòng)根據(jù)文章分類選擇分類文章模版顯示內(nèi)容,在后臺(tái)發(fā)布文章的時(shí)候,也沒有多出來一些操作,客戶很高興!
仔細(xì)考慮一下,上面的代碼還有完善的空間,比如是否可以和文章格式、自定義文章(頁面)模版一起工作,一起使用時(shí),選擇這些模版的優(yōu)先級(jí)怎么處理?如果你有更好的實(shí)現(xiàn)方法,歡迎在評(píng)論中提出,我們一起探討。


