想寫自己的 WordPress 外掛?別再只會複製貼上!資深工程師帶你從零打造第一個外掛

2025/09/15 | WP 開發技巧

想寫自己的 WordPress 外掛?別再只會複製貼上!資深工程師帶你從零打造第一個外掛

嗨,我是浪花科技的 Eric。身為一個天天跟 WordPress 打交道的工程師,我最常被問到的問題之一就是:「Eric,我想在網站上加一個XXX功能,但找不到適合的外掛,怎麼辦?」或是「我裝了一個外掛,結果網站就變慢了,有沒有更好的方法?」

每次聽到這些,我心裡都 OS:「兄弟,是時候掌握自己的力量了!」與其在茫茫外掛大海中尋覓,或是忍受一個功能包山包海、卻有 90% 你用不到的肥胖外掛,不如自己動手打造一個專屬於你的輕量級解決方案。這就是這篇文章誕生的目的:我要帶你走進 WordPress 外掛開發入門與實作 的世界,從最核心的觀念講起,手把手帶你從零開始,打造出你人生中的第一個 WordPress 外掛。別怕,這真的沒有你想像中那麼難!

為什麼要自己開發外掛?工程師的碎碎念時間

在我們開始寫程式碼之前,先讓我囉嗦一下,為什麼你該投資時間學習外掛開發。市面上不是有成千上萬個免費跟付費外掛嗎?

沒錯,但這就像去吃自助餐,菜色雖多,但你不一定每樣都愛吃,而且吃多了還會消化不良。自己開發外掛的好處是:

  • 絕對的控制權:你需要什麼功能,就寫什麼功能。不用再忍受外掛作者奇怪的設定介面或是不想要的功能。
  • 極致的效能:很多大型外掛為了滿足所有人的需求,載入了一大堆你根本用不到的 CSS 和 JavaScript 檔案,拖慢你的網站速度。自己寫的外掛,程式碼乾淨俐落,只在需要的時候執行,對效能絕對是一大福音。
  • 更高的安全性:你知道你寫的每一行程式碼是做什麼用的。相較之下,安裝來路不明或久未更新的外掛,就像是把家裡的鑰匙交給陌生人,風險太高了。
  • 無價的學習曲線:當你開始開發外掛,你會真正深入了解 WordPress 的運作核心。這不僅能讓你成為更好的開發者,未來在除錯、客製化網站時也會更加得心應手。

好了,說服時間結束。捲起你的袖子,讓我們來搞懂 WordPress 擴充功能的靈魂——Hooks。

WordPress 的任督二脈:搞懂 Hooks (Action & Filter)

如果你想在 WordPress 的世界裡客製化任何東西,就不能不認識 Hooks (鉤子)。你可以把它想像成 WordPress 核心程式在執行過程中,預先埋好的一個個「通知點」。當程式跑到這些點時,它會大喊一聲:「嘿!我現在要執行『顯示文章標題』這個動作了,有沒有人想對標題做點什麼事?」

這時候,你的外掛就可以舉手說:「有!我想在標題前面加上『HOT!』的字樣。」這個「舉手」的動作,就是透過 Hooks 來完成的。Hooks 分為兩種,搞懂它們的區別,你的 WordPress 開發功力就等於打通了任督二脈。

Action Hooks:在特定時間點「執行」動作

Action (動作) 就像是一個鬧鐘。當 WordPress 執行到某個特定的時間點(例如:載入頁首 `wp_head`、載入頁尾 `wp_footer`),它就會響起。你可以透過 `add_action()` 函式,把你寫好的函式「掛」到這個鬧鐘上,告訴 WordPress:「等一下鬧鐘響的時候,記得執行我的這個函式!」

舉個例子,如果你想在網站的 `<head>` 區塊插入一段 Google Analytics 的追蹤碼,你就可以這樣做:

function roamer_add_ga_code() { 
    // 這邊是你的 GA 追蹤碼 
    echo "<!-- Google Analytics -->"; 
} 
add_action('wp_head', 'roamer_add_ga_code');

Action 的重點在於「執行」,它不改變任何東西,只是在對的時間點,做你想做的事。

Filter Hooks:在資料傳遞中「過濾/修改」內容

Filter (過濾器) 則像是一個海關關卡。當 WordPress 有一筆資料要從 A 點送到 B 點時(例如:從資料庫取出文章內容 `the_content`,準備要顯示在畫面上),這筆資料必須通過這個關卡。你可以透過 `add_filter()` 函式,在關卡設置一個檢查員(你寫的函式),這個檢查員可以把這筆資料拿過來,加工一下,再放行。

例如,你想把文章內容中所有的「WordPress」這個字,都自動換成「最強大的 CMS – WordPress」,你就可以這樣做:

function roamer_modify_content($content) { 
    $new_content = str_replace('WordPress', '最強大的 CMS - WordPress', $content); 
    return $new_content; 
} 
add_filter('the_content', 'roamer_modify_content');

Filter 的重點在於「修改並回傳」,它一定會接收一個參數(原始資料),並且必須回傳一個參數(修改後的資料)。如果你忘了 `return`,那通過海關的資料就會變成空的,你的文章內容也就跟著消失了!

實戰開始:打造你的第一個外掛「文章預計閱讀時間」

理論說完了,我們來點實際的。接下來,我們將一步步打造一個簡單卻非常實用的外掛:自動計算並在文章開頭顯示「預計閱讀時間」。

第一步:建立外掛檔案結構

首先,進到你的 WordPress 安裝目錄,找到 `wp-content/plugins/` 這個資料夾。在裡面建立一個新的資料夾,名稱要獨特一點,避免跟其他外掛衝突。我們就叫做 `roamer-reading-time` 吧。

接著,在這個資料夾裡,建立一個 PHP 檔案,名稱跟資料夾一樣是最好的習慣:`roamer-reading-time.php`。

你的結構現在應該是: `wp-content/plugins/roamer-reading-time/roamer-reading-time.php`

第二步:撰寫外掛標頭 (Plugin Header)

這是最重要也最不能忘的一步。打開你剛剛建立的 `roamer-reading-time.php` 檔案,在最上面加上一段特殊格式的註解。WordPress 就是靠這段註解來辨識「喔,這是一個外掛」,並在後台顯示相關資訊。

<?php 
/** 
 * Plugin Name:       浪花文章閱讀時間 
 * Plugin URI:        https://roamer-tech.com/ 
 * Description:       自動計算並在文章開頭顯示預計閱讀時間。 
 * Version:           1.0.0 
 * Author:            Eric from Roamer Tech 
 * Author URI:        https://roamer-tech.com/ 
 * License:           GPL v2 or later 
 * License URI:       https://www.gnu.org/licenses/gpl-2.0.html 
 * Text Domain:       roamer-reading-time 
 */ 
 
// 防止檔案被直接存取,這是個好習慣 
if (!defined('ABSPATH')) { 
    exit; 
}

寫好存檔後,回到你的 WordPress 後台 > 外掛 > 已安裝的外掛,你應該就能看到「浪花文章閱讀時間」出現在列表裡了!先不要啟用它,因為我們還沒寫任何功能。

第三步:撰寫核心邏輯函式

我們的目標是計算文章字數,然後換算成閱讀時間。一般來說,中文閱讀速度大約每分鐘 300-500 字,英文約 200-250 字。為了簡單起見,我們抓個平均值,假設每分鐘 300 字。

在你的 PHP 檔案中,加入以下函式:

function roamer_calculate_reading_time($content) { 
    // 移除 HTML 標籤,避免計算到標籤本身 
    $stripped_content = strip_tags($content); 
 
    // 計算中文字數 (UTF-8) 
    $word_count = mb_strlen($stripped_content, 'UTF-8'); 
 
    // 假設每分鐘閱讀 300 字 
    $reading_minute = floor($word_count / 300); 
 
    // 如果計算出來小於 1 分鐘,就顯示 1 分鐘 
    if ($reading_minute < 1) { 
        $reading_minute = 1; 
    } 
 
    // 產生要顯示的 HTML 
    $reading_time_html = "<p class='roamer-reading-time'>🚀 預計閱讀時間: " . $reading_minute . " 分鐘</p>"; 
 
    return $reading_time_html; 
}

第四步:把功能掛到正確的 Filter Hook 上

我們已經有了計算時間的函式,現在要把結果加到文章內容的前面。這顯然是一個「修改」內容的行為,所以我們要用 Filter Hook,而最適合的鉤子就是 `the_content`。

我們需要一個「包裝函式」來呼叫我們的計算函式,並把結果跟原始文章內容組合起來。在檔案中繼續加入:

function roamer_display_reading_time($content) { 
    // is_single() 確保只在「單篇文章」頁面執行,避免出現在首頁或彙整頁面 
    // in_the_loop() 和 is_main_query() 是更保險的檢查,確保我們在 WordPress 主循環中 
    if (is_single() && in_the_loop() && is_main_query()) { 
        $reading_time_html = roamer_calculate_reading_time($content); 
        // 將我們的閱讀時間 HTML 放在原始文章內容 ($content) 的前面 
        return $reading_time_html . $content; 
    } 
 
    // 如果不是單篇文章頁面,就原封不動地回傳原始內容 
    return $content; 
} 
 
// 把我們的包裝函式掛到 the_content 這個 filter 上 
add_filter('the_content', 'roamer_display_reading_time');

注意到那個 `if (is_single() ...)` 了嗎?這是一個非常重要的防呆機制。身為工程師,我們要想得比使用者更多。如果你不加這個判斷,你的首頁文章列表、分類頁面,每一篇文章摘要前面都會出現閱讀時間,那版面就亂掉了。

現在,存檔!然後到 WordPress 後台啟用你的外掛。去看看任何一篇你的文章,是不是在最上面就出現了「🚀 預計閱讀時間: X 分鐘」的字樣了呢?恭喜你,你已經完成了你的第一個外掛!

持續進步:外掛開發的最佳實踐與下一步

完成第一個外掛只是開始,要成為一個好的 WordPress 開發者,還有一些觀念你必須知道:

  • 安全性是第一要務:永遠不要相信使用者的輸入。雖然我們這個外掛沒有使用者輸入,但未來若有,請務必使用 WordPress 內建的函式(如 `sanitize_text_field`)來清理資料,並在輸出到畫面上時使用 `esc_html` 或 `esc_attr` 來跳脫字元,防止 XSS 攻擊。
  • 程式碼組織:當外掛越來越複雜,不要把所有程式碼都塞在同一個檔案。可以建立 `includes` 資料夾來存放不同的功能模組,或使用 PHP 的物件導向 (OOP) 寫法來組織你的程式碼。
  • 國際化 (i18n):如果你希望你的外掛能被全世界的人使用,就要考慮到多國語系。使用 WordPress 的 `__()` 或 `_e()` 等函式來包裝你的字串,讓它們可以被翻譯。

總結:你已經踏上了開發者之路

今天,我們從 WordPress Hooks 的核心概念出發,一步步地分析、規劃並實作了一個完整的外掛。你不再只是一個 WordPress 的「使用者」,而是一個可以創造功能的「開發者」。

這趟 WordPress 外掛開發入門與實作 的旅程,最重要的不是你做出多華麗的功能,而是你理解了 WordPress 的擴充性是建立在 Action 和 Filter 這兩大基石上。掌握了它們,就等於掌握了客製化 WordPress 的鑰匙。未來不論是想串接第三方 API、建立自訂文章類型 (CPT),或是打造複雜的會員系統,底層的邏輯都是一樣的。

當然,開發之路還很長,會遇到各種 bug,會看到讓你一頭霧水的「死亡白畫面」,但這都是成長的過程。別怕,勇敢地在你的本地開發環境中去嘗試、去犯錯。每一次解決問題,都會讓你的功力更上一層樓。

如果你在開發的路上遇到了瓶頸,或是有更宏大的網站客製化想法,卻不知從何下手,浪花科技的團隊永遠在這裡。我們樂於將我們的技術經驗,轉化為你事業成功的助力。

延伸閱讀

有更複雜的 WordPress 客製化需求嗎?或是需要專業的技術顧問服務?
歡迎點擊這裡,填寫表單與我們聯繫,讓浪花科技的專業團隊為您打造高效、安全且獨一無二的網站解決方案!

常見問題 (FAQ)

Q1: 為什麼我的外掛寫好了,卻沒有出現在 WordPress 後台?

A: 最常見的原因是外掛主檔案最上方的「外掛標頭」(Plugin Header)註解格式不正確或遺失了。請仔細檢查 `/** ... */` 區塊內的 `Plugin Name:` 是否存在且格式無誤。這是 WordPress 辨識外掛的唯一依據。

Q2: Action Hook 和 Filter Hook 到底有什麼根本上的不同?

A: 最簡單的區分方式是:Action 是「在特定時間點,去『做』一件事」,它不預期會改變任何資料,像是在頁尾加上一段分析碼。而 Filter 則是「在資料傳遞過程中,去『改』這份資料」,它必須接收原始資料,並回傳修改後的資料,像是修改文章標題或內容。

Q3: 把客製化程式碼放在佈景主題的 functions.php 和自己寫一個外掛,哪個比較好?

A: 對於工程師來說,強烈建議寫成一個獨立的外掛。主要原因有三:1. **可攜性**:當你更換佈景主題時,外掛的功能依然存在,不會跟著舊主題消失。2. **組織性**:功能與外觀分離,程式碼結構更清晰,方便維護。3. **穩定性**:停用外掛很簡單,但 `functions.php` 寫錯可能導致整個網站崩潰,需要透過 FTP 才能修復。

 
立即諮詢,索取免費1年網站保固