WordPress 外掛與前端整合 – 範本

近期我寫了一套給開發者&自己用的套件,主要功能是簡化外掛開發時載入佈景主題範本的需求,以往在學習開發佈景主題時,常會看到上面這張圖來解釋 WordPress 範本的繼承關係:

這張圖很完整的說明當使用者造訪特定頁面時會對應的範本檔,這方面的知識可以參考 WordCamp Taipei 2019 的這場分享:「Barry Lin: WordPress 初學者世界,佈景結構概念談!」。既然範本檔主要是佈景主題在設計前台畫面使用的,跟開發外掛有什麼關係呢?事實上在實務中還滿常碰到的,像是如果你的外掛有新增自定義文章,就會需要設計該文章的範本,可能是文章內頁或是彙整頁。

此外,如果要在外掛中提供可重用的頁面範本,或是有針對 WooCommerce 的頁面進行某種程度的客製化,你的外掛都會需要載入範本,由於這些範本中的功能都是外掛所提供的,所以基本上不適合將它放在佈景主題的資料夾裡面,統一放在外掛目錄才好管理與維護,以下就外掛載入範本檔的具體方法進行介紹。

外掛結構

我們以一個叫做 wp-template 的範例外掛來說明,首先看到它的資料夾結構如下:

├── composer.json
├── composer.lock
├── src
├── templates
│   ├── archive-book.php
│   ├── author.php
│   ├── page-slug.php
│   ├── page-test.php
│   ├── single-book.php
│   ├── template-demo.php
│   ├── template-test.php
│   └── woocommerce
│       └── checkout
│           └── form-checkout.php
├── vendor
└── wp-template.php

templates 資料夾放的是對應的範本檔,可以看到有各種不同類型的範本:

Page Template

以 template 開頭的檔案如 template-demo.phptemplate-test.php 是可重用的頁面範本檔,可以讓使用者在後台的頁面管理中選擇使用。

Page Slug Remplate

以 page 開頭的檔案如 page-slug.php 以及 page-test.php,這會在頁面的網址代稱為 slug 或是 test 的時候所使用。

Post Type Template

該外掛註冊了一個自定義文章叫做 book,該文章的內頁以及彙整頁範本分別為 single-book.phparchive-book.php

WordPress Template

假設該外掛有一個需求是要客製化作者頁面,對應到的範本是 author.php,透過它就可以複寫佈景主題內建的作者頁面。

WooCommerce Template

另外如果要複寫 WooCommerce 的相關頁面,對應的是 WooCommerce 資料夾,資料夾的結構與檔案名稱要跟預設的一樣,這邊我們假設要客製化結帳頁面,因此需要的檔案是 form-checkout.php

取代範本的邏輯

WordPress 提供了一個動態勾點叫做 ${type}_template,可以判斷在不同的頁面下替換不同的範本,會回傳一個路徑,我們就是透過這個路徑來修改載入黨案,所有可使用的類型有:

  • 404_template
  • archive_template
  • attachment_template
  • author_template
  • category_template
  • date_template
  • embed_template
  • frontpage_template
  • home_template
  • index_template
  • page_template
  • paged_template
  • privacypolicy_template
  • search_template
  • single_template
  • singular_template
  • tag_template
  • taxonomy_template

舉替換作者頁為例,只要透過 author_template 這個勾點去載入外掛中的範本,就可以進行替換:

add_filter( 'author_template', 'set_author_template', 99, 1 );
function set_author_template( $template ) {
    $template = plugin_dir_path( __FILE__ ) . 'templates/author.php';
    return $template;
}

比較不一樣的是 WooCommerce,它用自己的勾點 wc_get_template 來處理,它帶有三個參數,可以讓我們進一步檢查外掛中是否有包含 WooCommerce 對應的範本檔,如果沒有的話就使用內建的範本:

add_filter( 'wc_get_template', 'intercept_wc_template', 99, 3 );
function intercept_wc_template( $template, $template_name, $template_path ) {
    $dir  = trailingslashit( plugin_dir_path( __FILE__ ) ) . 'templates/woocommerce/';
    $path = $dir . $template_name;
    return file_exists( $path ) ? $path : $template;
}

wp-template

由於在不同的情境下使用的勾點不同,用法也有些差異,因此我寫了一個介面來統一操作習慣,這樣之後就不需要再記要用哪個勾點了,該套件名稱為 wp-template,先使用 composer 進行安裝:

$ composer require oberonlai/wp-template

接下來在宣告類別時把範本的路徑帶入:

use ODS\Template;
$template = new Template( plugin_dir_path( __FILE__ ) . 'templates/' );

如果你的範本目錄是放在 yourpluign/views 底下,那就是變成 new Template( plugin_dir_path( __FILE__ ) . 'views/' ); 即可,記得最後的斜線不要漏掉。

新增可重用的頁面範本檔

使用 add_page() 方法來建立,帶有兩個參數:

  • $file – 範本檔案名稱
  • $name – 顯示在後台頁面管理範本下拉選單中的文字

範例如下:

use ODS\Template;
$template = new Template( plugin_dir_path( __FILE__ ) . 'templates/' );
$template->add_page( 'template-demo.php', '我的範本' );

要增加多個範本就呼叫多次 add_page()

$template->add_page( 'template-demo.php', '我的範本' );
$template->add_page( 'template-test.php', '他的範本' );
$template->add_page( 'template-your.php', '你的範本' );

新增頁面代稱範本

使用 add_page_slug() 方法建立,帶有兩個參數:

  • $file – 範本檔案名稱
  • $slug – 頁面代稱

範例如下:

use ODS\Template;
$template = new Template( plugin_dir_path( __FILE__ ) . 'templates/' );
$template->add_page_slug( 'page-test.php', 'test' );

這樣當使用者造訪頁面 https://example.com/test 的時候使用的就會是外掛的範本。

新增自定義文章範本

使用 add_post() 方法建立,帶有三個參數:

  • $file – 範本檔案名稱
  • $type – 自定義文章名稱
  • $position – 所在位置

範例如下:

use ODS\Template;
$template = new Template( plugin_dir_path( __FILE__ ) . 'templates/' );
$template->add_post( 'single-book.php', 'book', 'single' );
$template->add_post( 'archive-book.php', 'book', 'archive' );

複寫 WordPress 佈景主題範本

使用這個方法要特別小心,理論上要從外掛修改佈景主題的內容,請優先使用勾點來處理,複寫範本檔可能會造成後續維護上的困難,除非你有把握這個網站永遠都會是你經手,或是有清楚的交接文件,不然會害接手的人怎麼改都改不動。

使用 add_wp() 即可複寫,這個勾點的執行順序是 99,因此上述的問題要特別小心,該方法帶有兩個參數:

  • $file – 範本檔案名稱
  • $position – 所在位置

範例如下:

use ODS\Template;
$template = new Template( plugin_dir_path( __FILE__ ) . 'templates/' );
$template->add_wp( 'author.php', 'author' ); // 取代作者葉
$template->add_wp( '404.php', '404' ); // 取代 404 頁

複寫 WooCommerce 範本

使用 add_woocommerce() 方法建立,與 add_wp()一樣,優先使用勾點而非透過範本去修改頁面內容,因為 WooCommerce 常常會釋出範本更新,如果官方有更新而我們自己客製化的版本沒有跟上,可能就會發生預期外的狀況。

該方法不用帶任何參數,它會自動抓 templates/woocommerce 資料夾裡面的檔案,而該資料夾的結構記得要完全比照 WooCommerce 的規則,也就是 plugins/woocommerce/templates 裡面的結構以及檔案命名。

範例如下:

use ODS\Template;
$template = new Template( plugin_dir_path( __FILE__ ) . 'templates/' );
$template->add_woocommerce();

完整用法請參考:https://github.com/oberonlai/wp-template

使用這個套件可以一致性的載入我們所需的範本檔,減少記憶不同的用法,歡迎大家用看看,使用上有任何問題也可以跟我說!

文章標籤composer

目錄

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料

賴俊吾 / Oberon Lai
賴俊吾 / Oberon Lai

現為全職 WordPress 工程師,網站開發經歷 11 年,專攻前端工程與 WordPress 佈景主題、外掛客製化開發

訂閱電子報

Hi,我是 Oberon,我會固定在每週五早上發送接案心得以及與 WordPress 相關的電子報,同時也會分享一些實用的開發知識,讓你在 WordPress 的接案路上不孤單!

專注於分享 WordPress 開發、接案技巧、專案管理等自由工作者必備知識與心得

© 2024 想點創意科技有限公司

想點創意科技有限公司 | 統一編號 90516823
Designed by Hend Design | 隱私權政策

訂閱電子報

Hi,我是 Oberon,我會固定在每週五早上發送接案心得以及與 WordPress 相關的電子報,同時也會分享一些實用的開發知識,讓你在 WordPress 的接案路上不孤單!