使用 WordPress 子主題的終極指南

已發表: 2016-01-05

如果您想定制您在 HeroThemes 從我們這裡購買的主題,或者如果您正在使用定制設計為自己或您的客戶構建網站,那麼能夠利用 WordPress 子主題的力量是您所需要的。

在最基本的情況下,使用子主題將使您更有效率 - 將您用於每個項目的代碼保留在您自己的父主題中,或者使用像我們這樣的現成父主題,這意味著您堅持DRY(不要重複自己)原則。

但更進一步,您可以使用子主題和父主題創建具有核心代碼庫的站點網絡,您可以基於第三方主題框架構建自定義主題,或者您甚至可以創建自己的高級父主題以用作主題框架. 在本文中,我將簡要概述兒童主題的基本要素,然後向您展示一些更高級的技術。 您將學習:

  • 如何使用子主題使第三方父主題或主題框架適應您的項目需求
  • WordPress 如何對每個父主題和子主題中的模板文件進行優先級排序
  • 如何在子主題的函數文件中覆蓋父主題函數。

了解父子主題

理論上,任何主題都可以作為父主題,儘管有些主題更適合這個角色(包括我們的!)。 如果您正在使用我們的某個主題並希望針對您自己的項目對其進行調整,那麼使用子主題來執行此操作比破解主主題要好得多,這意味著您將在更新時丟失所有更改未來版本的主題。 要創建子主題,您只需創建一個新主題並將以下內容添加到其樣式表的開頭。 下面的示例使用 HeroThemes 主題 HelpGuru 作為父主題,但您可以使用任何主題,包括另一個 HeroTheme 的產品,例如 KnowAll。

立即開始建立您的知識庫!

我們的 KnowAll 主題包括一個子主題,可幫助您自定義知識庫站點

獲取主題
/*
Theme Name: My child theme
Theme URI: URL of the theme or site it's used for
Description: Description of what the theme is for and its main features.
Author: Your name
Template: helpguru
Version: 1.0
*/
@import url("../helpguru/css/style.css");

重要的幾行是這兩行:

Template: helpguru
@import url("../helpguru/css/style.css");

第一部分指定模板,它告訴 WordPress 這是一個子主題,它的父主題是 HelpGuru 主題。 請注意,您在這裡使用父主題文件夾的名稱而不是主題的名稱(所以上面我使用了“helpguru”,而不是“HelpGuru”)。

HelpGuru 可以使用子主題進行轉換
HelpGuru 可以使用子主題進行轉換

第二部分從父主題導入樣式表,這意味著所有父主題的樣式都將在您的子主題中激活。 然後,您在此@import聲明下方添加自己的樣式 - 這意味著將使用兩個主題的樣式,但是如果兩個樣式表中都存在同一元素的聲明,則子主題的 CSS 將由於級聯而佔上風(作為您的子主題的樣式來自父主題的樣式)。

一個子主題可以包含一個樣式表,如果您願意,可以只包含一個樣式表,在這種情況下,您將使用它來做的就是覆蓋一些父主題的樣式。 或者,您可以添加額外的模板文件和/或函數文件,在這種情況下,您需要了解 WordPress 如何從您的父主題和子主題訪問模板文件。

父子主題模板文件

WordPress 在父子主題中使用模板文件的方式非常簡單。 當顯示給定頁面(或帖子或任何其他內容類型)時,WordPress 將根據模板層次結構使用父主題或子主題中最相關的模板文件。 如果它找到同一個模板文件的兩個版本,它將使用子主題中的一個。 這意味著您的子主題的模板文件將在兩種情況下覆蓋父主題的模板文件:

  • 如果您的子主題包含的模板文件在層次結構中高於父主題中的模板文件;
  • 或者如果您的父主題和子主題都包含所需模板文件的版本。

決定父主題模板文件還是子主題模板文件

WordPress 將使用模板層次結構來確定要使用的模板文件,但這會與您在每個父主題和子主題中的文件交互。 簡單來說,WordPress 經歷了三個步驟:

  1. 它標識正在顯示的內容的類型。
  2. 它通過模板層次結構工作,直到找到一個文件來顯示該內容,無論是在父主題還是子主題中。
  3. 如果該文件同時存在於父主題和子主題中,則它使用來自子主題的文件。

讓我們用一個例子來說明這一點。 下表顯示了兩個假設主題中的模板文件集,其中一個是另一個的子主題。 我強調的文件優先。

WordPress 如何選擇要使用的模板
WordPress 如何選擇要使用的模板

所以在上面的例子中,讓我們看看哪些模板文件將用於顯示某些類型的內容:

  • “產品”自定義帖子類型的單個帖子將使用子主題中的single-product.php顯示。
  • 其他帖子類型(包括普通帖子)的單個帖子將使用子主題中的single.php顯示。
  • 靜態頁面將使用父主題中的page.php顯示。
  • 小部件類別的列表將使用子主題中的category-widgets.php顯示。
  • 其他類別列表將使用父主題中的category.php顯示。
  • 其他存檔列表將使用父主題中的archive.php顯示。
  • 搜索結果將使用父主題中的search.php顯示。
  • 404 頁面將使用父主題中的404.php顯示。
  • 其他沒有特定模板文件的頁面將使用子主題中的index.php顯示。

更進一步——覆蓋父主題功能

除了覆蓋或補充父主題中的 CSS 和/或模板文件之外,您還可以使用子主題來覆蓋父主題中的功能或添加額外的功能。

警告! 如果您使用子主題只是為了添加額外的功能,那麼您最好編寫一個插件。 不幸的是,父主題和子主題中的函數文件與樣式表的交互方式不同,實際上它們以相反的方式工作(令人困惑,我知道)。 WordPress 在子主題之後調用父主題中的函數,這意味著它們可以覆蓋子主題的函數。 我知道這聽起來有點痛苦:您創建了一個子主題,因為這就是您想要在您的網站中使用的內容,對吧? 好吧,幸運的是有辦法克服這個問題。 第一種方法是您在子主題中使用的方法,即在將函數附加到相關操作或過濾器掛鉤時設置優先級。 第二個是在父主題中完成的,這是為了使您的功能可插入。 稍後我會談到這一點,但首先讓我們看看您的孩子主題中的方法。

使用優先級覆蓋父主題功能

要激活您在子主題中添加的每個功能,您需要使用add_action()add_filter()將其附加到操作掛鉤或過濾器掛鉤。 add_action()add_filter()函數具有三個參數:

  • $tag – 動作或過濾鉤子的唯一標識符
  • $function_to_add – 函數的名稱
  • $priority - 你想掛接你的函數的優先級(很快就會有更多)

使用add_filter()您可以使用第四個可選參數$arguments ,但這與子主題並不特別相關。 在大多數情況下,只使用前兩個參數(這兩個參數都是必需的),但您可以使用可選的$priority參數將父主題中的函數覆蓋為子主題中的函數。 優先級越高,加載越晚:默認為10 ,因此如果父主題沒有指定優先級,您只需將子主題中的優先級設置為高於 10 的數字。讓我們看看這是如何實現的作品。 假設您正在使用 HelpGuru 主題的子項,並且您想要覆蓋菜單功能並添加您自己的功能。 這個主題包括ht_theme_setup()函數來設置主題(包括註冊菜單,添加特色圖像支持等等),它附加到after_setup_theme動作掛鉤。 HelpGuru的functions文件中的代碼如下:

if ( ! function_exists( 'ht_theme_setup' ) ) :
function ht_theme_setup() {
// contents of function
}
}
add_action( 'after_setup_theme', 'ht_theme_setup' );

要在您的子主題中覆蓋ht_theme_setup()函數的元素(但不是全部:我們很快就會談到),您將編寫一個函數來替換 HelpGuru 提供的功能元素並將其附加到after_setup_theme操作掛鉤,指定高於 10 的優先級:

function my_theme_setup() {
// contents of function
}
add_action( 'after_setup_theme', 'my_theme_setup', 15 );

當 WordPress 遇到這些附加到同一個鉤子的函數時,它會首先觸發較低優先級的函數,即來自父主題的函數。 然後它將從您的子主題中觸發更高優先級的主題,這意味著它可以覆蓋父主題中的功能。 正如我上面提到的,還有另一種方法,最好將其寫入您的主題中,這樣它們就可以更容易地用作父主題,這就是使您的函數可插入。

使用可插入函數來允許子主題覆蓋

由於 WordPress 在子主題中傳遞父主題中的函數,因此您可以對父主題的函數進行編碼,以便它們檢查子主題中具有相同名稱的函數,如果存在,則父主題函數不存在通過了。 您可以使用條件語句來執行此操作,就像我們在 HelpGuru 上面看到的那樣:

if ( ! function_exists( 'ht_theme_setup' ) ) :
function ht_theme_setup() {
// contents of function
}
}

如果沒有同名的函數已經被傳遞(例如在子主題中),來自父主題的函數將被傳遞。 但是如果 WordPress 已經遇到過具有此名稱的函數,它將忽略可插入函數(即父主題中的函數)。 為了使這項工作,您只需在您的子主題中創建與您想要覆蓋的父主題中的名稱相同的函數。 因此,要完全覆蓋ht_theme_setup()函數,您可以在子主題中使用它:

function ht_theme_setup() {
// contents of function
}

而已! 只需編寫另一個具有相同名稱的函數,它將覆蓋父主題中的函數。 注意:此技術僅在您創建自己的父主題時才有效——不要試圖在第三方父主題中編輯函數文件以使其可插入。 畢竟,創建子主題的全部意義在於不要觸碰父主題!


概括

正如我希望我已經證明的那樣,使用子主題可以提高您作為 WordPress 開發人員的效率和效力,特別是如果您為客戶或您自己開發自定義網站。 至少,使用現有主題的子主題(例如我們的 HeroThemes 之一)可以使您的開發工作流程更快、更高效,因為它可以節省您一遍又一遍地做同樣的工作。

您可以通過使用子主題的模板文件和函數文件來覆蓋或補充父主題的功能,從而進一步實現這一點。 如果您真的想將子主題發揮到極致,您可以構建自己的父主題,為您提供所有新項目的快速起點,讓您可以比從頭開始更輕鬆地為子主題添加更多內容.