~/blog/wordpress-first-useful-plugin-development-guide.md
WordPress 開發與技巧 · 2025 / 08 / 22 · 2 views

Hello World 之後呢?打造第一個真正有用的 WordPress 外掛開發實戰

Eric — 浪花科技創辦人 / AI 架構師
Eric
浪花科技創辦人 · AI 架構師
Hello World 之後呢?打造第一個真正有用的 WordPress 外掛開發實戰
目錄 table-of-contents.md

印出 Hello World 之後,你的 WordPress 外掛之路是不是就斷在那裡了?網路上一百篇教學教你起步,卻很少有人帶你走完下一哩路——就像駕訓班教練只教你發動引擎,然後就叫你上高速公路。這篇從零打造一個「真正有用」的外掛,把 Hook、設定頁、資料處理一次練齊。

今天,我這個有點囉嗦的工程師就要帶你跨出那關鍵的下一步。我們不只做「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

常見問題

WordPress 怎麼辨識一個外掛?
WordPress 是靠寫在主 PHP 檔案最上方的「外掛標頭」(Plugin Header)來辨識外掛,而非靠檔名。標頭是一段 PHP 註解,記錄外掛名稱、作者、版本、授權等資訊,其中 Plugin Name 為必填,缺少它後台就不會顯示這個外掛。
開發 WordPress 外掛為什麼要用獨立資料夾,而不是單一 PHP 檔?
用獨立資料夾包起整個外掛是為了可擴展性與整潔。外掛日後可能加入 CSS、JavaScript 或其他 PHP 檔案,事先建立專屬資料夾可避免 wp-content/plugins 目錄變得雜亂。
WordPress 外掛裡為什麼常看到 if ( ! defined( 'ABSPATH' ) ) exit; 這行?
這是一道基本安全防線,用來防止他人透過 URL 直接存取該 PHP 檔案。當檔案被直接存取時 ABSPATH 常數未定義,程式會立即中止執行,幾乎所有專業外掛與主題都會加上這行。
如何在 WordPress 註冊一個自訂短代碼(Shortcode)?
使用 add_shortcode() 函數註冊,它接收兩個參數:短代碼名稱與回呼函數。當該短代碼在文章中被使用時,WordPress 會執行對應的回呼函數並回傳輸出內容。建議將回呼函數加上獨特前綴以避免與其他外掛命名衝突。
短代碼的回呼函數中 $atts 與 $content 分別代表什麼?
$atts 是使用者在短代碼上傳入的屬性(Attributes),$content 則是包在開始與結束標籤之間的內容。可搭配 shortcode_atts() 設定屬性預設值,並用 esc_html()、esc_attr()、sanitize_html_class() 等函數淨化輸出以提升安全性。
~/roamer-tech/newsletter // FREE
// newsletter

訂閱免費電子報

把 AI 自動化、企業系統設計與 WordPress / Laravel 開發的真實案例和可直接照做的技巧,整理成電子報寄給你。只寄精選內容、不灌垃圾信,一鍵就能退訂。

$
// final.exec()

準備好讓你的網站開始為你工作了嗎?