別再只會 echo ‘Hello World’!資深工程師帶你打造第一個『真正有用』的 WordPress 外掛

2025/08/22 | WP 開發技巧

別再只會 echo ‘Hello World’!資深工程師帶你打造第一個『真正有用』的 WordPress 外掛

嗨,我是浪花科技的 Eric。在網路上搜尋「WordPress 外掛開發教學」,你大概會看到一百篇教你如何建立一個只會印出「Hello World」的外掛。沒錯,那是一個起點,但然後呢?很多教學就停在這裡了,讓你望著那行孤單的文字,不知道下一步該往哪走。說實話,這種感覺就像是駕訓班教練只教你發動引擎,然後就叫你上高速公路一樣,有點不負責任啦。

今天,我這個有點囉嗦的工程師就要帶你跨出那關鍵的下一步。我們不只做「Hello World」,我們要打造一個「真正有用」的外掛。這個外掛或許很簡單,但它會涵蓋外掛開發的核心概念:檔案結構、鉤點(Hooks)、短代碼(Shortcode),以及一些重要的開發好習慣。準備好了嗎?泡杯咖啡,打開你的編輯器,我們來寫點真正能派上用場的 Code!

WordPress 外掛的骨架:不只是個 PHP 檔案

在我們開始寫任何功能之前,必須先理解 WordPress 是如何「辨識」一個外掛的。它不是靠檔名,也不是靠你虔誠的祈禱,而是靠一個寫在 PHP 檔案最上方的「外掛標頭」(Plugin Header)。這就像是一個外掛的身分證,告訴 WordPress 它的名字、作者、版本等重要資訊。

一個最基本的外掛結構長這樣:

  • 一個專屬的資料夾,例如 my-first-useful-plugin
  • 一個主要的 PHP 檔案,例如 my-first-useful-plugin.php

為什麼要多此一舉用資料夾包起來?工程師的囉嗦時間又到了:這是為了「可擴展性」和「整潔」。未來你的外掛可能會需要加入 CSS、JavaScript 檔案,或是其他的 PHP 檔案。從一開始就把所有東西都放在一個專屬的資料夾裡,才不會讓你的 wp-content/plugins 目錄變成一場災難。相信我,你未來的同事(或幾個月後的你自己)會感謝你今天的好習慣。

關鍵的身分證:外掛標頭 (Plugin Header)

打開你的主 PHP 檔案,在最一開始的地方,我們要加入這段註解。這就是外掛的身分證:

<?php
/**
 * Plugin Name:       我的第一個實用外掛
 * Plugin URI:        https://roamer-tech.com/
 * Description:       這是一個用來展示短代碼功能的示範外掛,比 Hello World 有用多了!
 * Version:           1.0.0
 * Author:            Eric @ 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:       my-first-useful-plugin
 * Domain Path:       /languages
 */

// 如果這個檔案被直接存取,就中止執行。保護你的程式碼是基本功!
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

這裡面,Plugin Name 是最重要的,沒有它,WordPress 根本不會在後台顯示你的外掛。其他的欄位也都盡量填寫完整,這是一個專業開發者的表現。特別注意最後那段 if ( ! defined( 'ABSPATH' ) ),這是一道基本的安全防線,防止有人直接透過 URL 存取你的 PHP 檔案,幾乎所有專業的外掛和主題都會有這行,把它當成你的起手式吧!

實戰開始:打造一個可客製化的「公告」短代碼

我們的目標是建立一個短代碼,讓使用者可以在文章或頁面中輕鬆插入一個樣式化的公告訊息。例如,輸入 [my_announcement]這是一則重要的公告![/my_announcement],就會顯示一個漂亮的公告框。

步驟一:註冊你的短代碼

我們要用 WordPress 提供的 add_shortcode() 函數來「註冊」我們的短代碼。這個函數需要兩個參數:短代碼的名稱(別人要輸入的文字),以及一個回呼函數( जब這個短代碼被觸發時要執行的 PHP 函數)。

在你的主 PHP 檔案中,加入以下程式碼:

function roamer_tech_announcement_shortcode( $atts, $content = null ) {
    // 短代碼的邏輯會寫在這裡
    return '<div class="roamer-announcement">' . esc_html( $content ) . '</div>';
}
add_shortcode( 'my_announcement', 'roamer_tech_announcement_shortcode' );

看到了嗎?我把函數命名為 roamer_tech_announcement_shortcode。這就是我前面提到的「前綴」(Prefixing)。在 WordPress 的世界裡,所有的外掛和主題的函數都活在同一個全域命名空間中。如果你把函數取名為 announcement_shortcode(),萬一有另一個外掛也用了同樣的名稱,網站就直接白畫面給你看。所以,養成幫所有自訂函數、類別、常數加上獨特前綴的習慣,是避免衝突的救命丹。

在上面的程式碼中,我們的函數接收了兩個參數:$atts (Attributes,屬性) 和 $content(內容)。$content 就是使用者包在 [my_announcement][/my_announcement] 之間的文字。我們用 esc_html() 把它包起來,這又是一個重要的安全習慣,確保輸出的內容是乾淨的,避免潛在的 XSS 攻擊。

步驟二:讓短代碼更靈活 – 加入屬性 (Attributes)

現在我們的短代碼只能顯示一種樣式。如果我們想讓使用者可以自訂公告的類型(例如:資訊、警告、成功)呢?這時候就要用到 $atts 了。

我們來修改一下函數,讓它可以接收一個 type 屬性,例如 [my_announcement type="warning"]警告訊息[/my_announcement]

function roamer_tech_announcement_shortcode( $atts, $content = null ) {
    // 1. 設定預設屬性值
    $attributes = shortcode_atts(
        array(
            'type' => 'info', // 預設是 'info' 類型
        ),
        $atts
    );

    // 2. 根據屬性決定 CSS class
    $class = 'roamer-announcement ' . 'roamer-announcement-' . sanitize_html_class( $attributes['type'] );

    // 3. 組合並回傳 HTML
    if ( ! empty( $content ) ) {
        return '<div class="' . esc_attr( $class ) . '">' . esc_html( $content ) . '</div>';
    }
    return ''; // 如果沒有內容,就回傳空字串
}
add_shortcode( 'my_announcement', 'roamer_tech_announcement_shortcode' );

這裡多了幾個新東西:

  • shortcode_atts(): 這是 WordPress 的一個超實用函數。它會幫你合併使用者傳入的屬性 ($atts) 和你設定的預設值。如果使用者沒有提供 type 屬性,它就會自動使用預設的 'info'
  • sanitize_html_class(): 另一個安全函數。它會確保從屬性拿到的值是合法的 CSS class 名稱,過濾掉不安全的字元。
  • esc_attr(): 用來淨化要放在 HTML 屬性裡的內容(例如 class="...")。

你看,一個看似簡單的功能,背後卻隱含了許多關於預設值處理、安全性、程式碼健壯性的思考。這就是工程師的日常。

步驟三:加上一點樣式

只有 HTML 是不夠的,我們需要一點 CSS 讓它看起來更專業。我們需要一個方法把 CSS 檔案「注入」到網站前端。最好的方法就是使用 WordPress 的鉤點 (Hook)。

我們使用 wp_enqueue_scripts 這個 Action Hook 來載入我們的 CSS。

// 將 CSS 檔案排入佇列
function roamer_tech_enqueue_styles() {
    // 註冊並載入 CSS
    wp_enqueue_style(
        'roamer-plugin-styles', // 給這個樣式一個獨特的 handle (名稱)
        plugin_dir_url( __FILE__ ) . 'assets/css/style.css', // CSS 檔案的路徑
        array(), // 這個 CSS 依賴的其他樣式 handle,這裡沒有
        '1.0.0' // 版本號
    );
}
add_action( 'wp_enqueue_scripts', 'roamer_tech_enqueue_styles' );

這段程式碼做了幾件事:

  1. 我們定義了一個函數 roamer_tech_enqueue_styles
  2. 在函數裡,我們使用 wp_enqueue_style() 來告訴 WordPress:「嘿,幫我把這個 CSS 檔案加到網頁的 <head> 裡」。
  3. plugin_dir_url( __FILE__ ) 是一個魔法函數,它會自動取得你外掛資料夾的 URL 路徑,確保路徑永遠是正確的。
  4. 最後,我們用 add_action() 把我們的函數「掛」到 wp_enqueue_scripts 這個鉤點上。這表示當 WordPress 準備要輸出前端的 scripts 和 styles 時,就會執行我們的函數。

現在,你需要在你的外掛資料夾裡建立一個 assets/css/ 的路徑,然後在裡面放一個 style.css 檔案。內容大概像這樣:

/* My First Useful Plugin Styles */
.roamer-announcement {
    padding: 15px 20px;
    margin: 20px 0;
    border-left: 5px solid #0073aa;
    background-color: #f7f7f7;
    border-radius: 4px;
}

.roamer-announcement-info {
    border-left-color: #0073aa; /* 藍色 */
}

.roamer-announcement-warning {
    border-left-color: #ffb900; /* 黃色 */
    background-color: #fff8e5;
}

.roamer-announcement-success {
    border-left-color: #46b450; /* 綠色 */
    background-color: #f0f8f2;
}

到這裡,把你的外掛打包成 .zip 上傳到 WordPress 後台,啟用它。然後到任何一篇文章或頁面,用文字編輯器輸入:

[my_announcement type="warning"]這是一則警告訊息![/my_announcement]

[my_announcement type="success"]操作成功![/my_announcement]

你應該就能看到我們精心設計的公告框了!

總結:從「Hello World」到解決問題

恭喜你!你已經完成了你的第一個「真正有用」的 WordPress 外掛。我們從最基本的檔案結構和標頭開始,學習了如何用 add_shortcode 建立一個可擴展的功能,並透過 add_actionwp_enqueue_style 掌握了載入資源的正確方式。更重要的是,我們在過程中不斷強調了前綴、程式碼安全這些專業開發中不可或缺的好習慣。

這只是一個開始。WordPress 外掛開發的世界非常廣闊,還有 Settings API、Custom Post Types、REST API 等著你去探索。但今天你所學到的,是通往那片廣闊天地的堅實基礎。記住,寫程式不只是為了讓電腦執行指令,更是為了解決實際問題。從今天起,試著去想:「有什麼重複性的工作,可以寫個小外掛來自動化?」當你開始用這種思維模式看待 WordPress,你的開發功力將會突飛猛進。

延伸閱讀

如果你在開發路上遇到了任何瓶頸,或是你的企業有更複雜的 WordPress 客製化需求,別忘了浪花科技的團隊隨時都在這裡。我們不只寫程式,我們打造解決方案。

立即聯繫浪花科技,讓我們成為你最強大的技術後盾。

常見問題 (FAQ)

Q1: 為什麼一定要幫我的 PHP 函數加上「前綴」(Prefix)?

A1: 因為 WordPress 的所有外掛和主題的程式碼都運行在同一個「全域命名空間」下。如果你定義了一個很通用的函數名稱,例如 get_posts(),非常有可能會和 WordPress 核心或其他外掛的函數名稱衝突,導致 PHP 致命錯誤 (Fatal Error),也就是俗稱的「死亡白畫面」。加上一個獨一無二的前綴(例如你的公司或外掛縮寫)是避免這種災難最簡單也最有效的方法。

Q2: 除了短代碼 (Shortcode),還有其他在文章中插入動態內容的方法嗎?

A2: 有的!隨著 WordPress 區塊編輯器 (Gutenberg) 的普及,現在更推薦的方法是開發「自訂區塊」(Custom Block)。自訂區塊提供了更佳的使用者體驗,使用者可以直接在編輯器中看到預覽效果,並透過側邊欄的選項來設定,比記憶短代碼的屬性要直觀得多。我們在延伸閱讀中有提供相關教學,建議在熟悉短代碼後可以深入研究。

Q3: `add_action` 和 `add_filter` 到底有什麼不一樣?

A3: 這是個好問題!簡單來說,add_action 是用來在 WordPress 運行的特定時間點「執行某個動作」,例如我們用它來載入 CSS 檔案。它通常不期望你回傳任何東西。而 add_filter 則是用來「修改」資料的,它會接收一個值,讓你對它進行處理後,再把修改後的值「回傳」回去。例如,你可以用 filter 來修改文章標題的顯示方式。可以參考我們關於 Hooks 的深度文章來了解更多細節。

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