Hướng dẫn toàn diện phát triển plugin WordPress: Xây dựng plugin đầu tiên của bạn từ con số 0

Đọc trong 3 phút
2026-03-19
2026-06-03
2,726
Tôi kiếm được hoa hồng khi bạn mua sắm thông qua các liên kết dưới đây, mà không phát sinh thêm chi phí nào cho bạn.

Công tác chuẩn bị và thiết lập môi trường

Trước khi bắt đầu viết mã, bạn cần một môi trường phát triển phù hợp. Điều này bao gồm một phiên bản WordPress được cài đặt trên máy tính cá nhân, một trình soạn thảo mã, và một số kiến thức cơ bản về PHP. Các công cụ được khuyến nghị để thiết lập môi trường phát triển trên máy tính cá nhân bao gồm XAMPP, MAMP, hoặc Local by Flywheel – những công cụ này cho phép bạn nhanh chóng thiết lập một môi trường máy chủ chứa PHP và MySQL trên hệ thống của mình.

Tạo thư mục và tệp cơ bản cho plugin

Mọi plugin WordPress đều phải có một tệp chính (main file), và tệp này chính là điểm khởi đầu (entry point) của plugin đó. Đầu tiên, bạn cần phải… wp-content/plugins của bạn, ví dụ my-first-pluginSau đó, hãy tạo một tệp PHP chính bên trong thư mục đó; tên tệp này thường trùng với tên của thư mục. my-first-plugin.php

Đầu tiên của tệp chính này phải chứa một phần chú thích tiêu đề thông tin plugin tiêu chuẩn. WordPress sẽ đọc những thông tin này để nhận diện và hiển thị plugin của bạn trên giao diện quản trị nền.

Đọc thêm Từ Không Đến Có: Hướng Dẫn Từng Bước Nắm Vững Kỹ Năng Trọng Tâm Phát Triển Plugin WordPress

<?php
/**
 * Plugin Name:       我的第一个插件
 * Plugin URI:        https://example.com/my-first-plugin
 * Description:       这是一个用于学习 WordPress 插件开发的示例插件。
 * Version:           1.0.0
 * Author:            你的名字
 * Author URI:        https://example.com
 * License:           GPL v2 or later
 * Text Domain:       my-first-plugin
 * Domain Path:       /languages
 */

Hiểu cấu trúc cơ bản của phát triển plugin WordPress

Một plugin có chức năng đầy đủ thường không chỉ bao gồm một tệp tin duy nhất. Ngoài tệp tin chính, bạn còn có thể sở hữu các tệp tin chứa mã JavaScript, CSS, hình ảnh, cùng các tệp ngôn ngữ dùng cho việc hỗ trợ quốc tế hóa (internationalization). Một cấu trúc thư mục hợp lý sẽ giúp tổ chức và bảo trì mã nguồn một cách dễ dàng hơn.

UltaHost – Nhà cung cấp dịch vụ máy chủ WordPress chuyên nghiệp
Bảo đảm hoàn tiền trong 30 ngày, băng thông và cơ sở dữ liệu không giới hạn, bảo vệ DDoS miễn phí, mua 3 năm ưu đãi 50%

Một cấu trúc được đề xuất như sau:
- my-first-plugin/ (Thư mục gốc của tiện ích mở rộng)
- my-first-plugin.php (Tập tin chính)
- includes/ (Lưu trữ các tệp chứa các lớp hoặc hàm chức năng cốt lõi)
- admin/ (Có chứa mã nguồn liên quan đến giao diện quản trị nền)
- public/ (Nơi lưu trữ mã nguồn liên quan đến việc hiển thị trên giao diện người dùng – Front-end display code)
- assets/ (Nơi lưu trữ các tài nguyên như CSS, JavaScript, hình ảnh, v.v.)
- languages/ (Nơi lưu trữ các tệp dịch thuật quốc tế)

Viết mã PHP cốt lõi

Tất cả các chức năng và logic của plugin đều được thực hiện thông qua mã PHP. WordPress cung cấp một số lượng lớn…动作钩子过滤器钩子Đây chính là nền tảng cơ bản cho sự tương tác giữa các plugin và phần cốt lõi của WordPress.

Thực hiện một chức năng mã ngắn đơn giản

Các mã ngắn (short codes) là những công cụ mạnh mẽ giúp người dùng dễ dàng nhúng các tính năng của plugin vào bài viết hoặc trang web. Chúng ta hãy cùng tạo một mã ngắn đơn giản để hiển thị một lời chào trên trang web.

Trong tệp chính của bạn… my-first-plugin.php Dưới phần chú thích ở đầu, hãy thêm các hàm và hook sau đây:

Đọc thêm Phân Tích Sâu Về Phát Triển Plugin WordPress: Xây Dựng Tiện Ích Mở Rộng Đầu Tiên Từ Không Đến Có

// 注册短代码
function mfp_greeting_shortcode( $atts ) {
    // 使用 shortcode_atts 设置默认参数并合并用户传入的参数
    $atts = shortcode_atts( array(
        'name' =&gt; '访客',
    ), $atts, 'mfp_greeting' );

// 返回要显示的内容
    return '<p>Xin chào, '. esc_html($atts['name'])'. ‘! Chào mừng bạn sử dụng plugin đầu tiên của tôi.</p>'php
add_shortcode('mfp_greeting', 'mfp_greeting_shortcode');

Bây giờ, người dùng có thể nhập nội dung vào trình soạn thảo bài viết. [mfp_greeting name=“小明”]Trong trường hợp này, phía trước (frontend) sẽ hiển thị dòng chữ: “Xin chào, Minh Nhỏ! Chào mừng bạn sử dụng tiện ích mở rộng (plugin) đầu tiên của tôi.”

Thêm một tùy chọn cấu hình vào phần quản trị nền (backend).

Để các tính năng của plugin có thể được cấu hình, chúng ta thường cần thêm một trang thiết lập. Ở đây, chúng ta sẽ hướng dẫn cách thêm một trang menu con vào menu “Thiết lập”.

Trước hết, chúng ta sử dụng… add_action Các công cụ hỗ trợ quản trị (hooks) được đăng ký và cấu hình khi quản trị viên thực hiện việc khởi tạo hệ thống.

Hosting.com - lưu trữ chia sẻ
Hiệu năng cao, được trang bị CPU AMD EPYC, lưu trữ SSD NVMe và LiteSpeed, hỗ trợ chuyên gia nội bộ 24 giờ/ngày, các biện pháp bảo mật tiên tiến bao gồm SSL, chống brute force, phần mềm độc hại và bảo vệ DDoS, tiết kiệm tới 73%.
// 初始化插件设置
function mfp_settings_init() {
    // 注册一个新的设置 section
    add_settings_section(
        'mfp_settings_section', // section ID
        '我的插件设置', // 标题
        'mfp_settings_section_callback', // 回调函数,用于输出 section 描述
        'general' // 显示在哪个设置页,这里是“常规”设置页
    );

// 在 section 内注册一个字段
    add_settings_field(
        'mfp_default_greeting', // 字段 ID
        '默认问候人名', // 字段标题
        'mfp_default_greeting_callback', // 渲染字段输入框的回调函数
        'general', // 设置页面
        'mfp_settings_section' // 所属 section
    );

// 在 WordPress 的 `option` 表中注册这个设置
    register_setting( 'general', 'mfp_default_greeting' );
}
add_action( 'admin_init', 'mfp_settings_init' );

Sau đó, hãy định nghĩa hai hàm gọi lại (callback functions) đã được sử dụng ở trên để hiển thị giao diện:

// Section 描述的回调函数
function mfp_settings_section_callback() {
    echo '<p>Tại đây, tôi sẽ cấu hình các tùy chọn liên quan đến plugin đầu tiên của mình.</p>';
}

// 字段输入框的回调函数
function mfp_default_greeting_callback() {
    // 从数据库获取已保存的值,如果没有则使用默认值
    $option = get_option( 'mfp_default_greeting', 'WordPress 用户' );
    // 输出一个输入框
    echo '<input type="text" name="mfp_default_greeting" value="' . esc_attr( $option ) . '" />';
}

Bây giờ, bạn có thể thấy tùy chọn cài đặt này ở phía dưới trang “Cài đặt -> Chung” trong giao diện quản trị WordPress.

Quản lý tài nguyên phía trước (front-end resources) và tương tác với Ajax

Các plugin hiện đại thường yêu cầu có phong cách thiết kế (styles) và logic tương tác (interaction logic) riêng của chúng. WordPress cung cấp những phương thức tiêu chuẩn để đăng ký và tải các tệp CSS cũng như JavaScript một cách an toàn.

Đọc thêm Bắt Đầu Từ Con Số 0: Tại Sao Nên Chọn Phát Triển Plugin WordPress

Tải CSS và JavaScript một cách an toàn

Đừng bao giờ trực tiếp thực hiện điều đó trong các tệp PHP của bạn. <link><script> Nên sử dụng cách mã hóa cứng đường dẫn tài nguyên trong các thẻ (tags). wp_enqueue_stylewp_enqueue_script Hàm.

// 注册并加载前端资源
function mfp_enqueue_public_assets() {
    // 加载一个 CSS 文件
    wp_enqueue_style(
        'mfp-public-style', // 样式表句柄
        plugin_dir_url( __FILE__ ) . 'assets/css/public-style.css', // 样式表 URL
        array(), // 依赖项
        '1.0.0' // 版本号,可用于清除缓存
    );

// 加载一个 JavaScript 文件
    wp_enqueue_script(
        'mfp-public-script', // 脚本句柄
        plugin_dir_url( __FILE__ ) . 'assets/js/public-script.js', // 脚本 URL
        array( 'jquery' ), // 依赖项,这里依赖 jQuery
        '1.0.0',
        true // 是否在页面底部加载
    );

// 重要:将 PHP 变量安全地传递到 JavaScript
    wp_localize_script(
        'mfp-public-script',
        'mfp_ajax_object', // 在 JS 中访问的对象名
        array(
            'ajax_url' => admin_url( 'admin-ajax.php' ),
            'nonce'    => wp_create_nonce( 'mfp_ajax_nonce' ),
            'default_name' => get_option( 'mfp_default_greeting', 'WordPress 用户' )
        )
    );
}
// 在前端页面加载资源
add_action( 'wp_enqueue_scripts', 'mfp_enqueue_public_assets' );
// 在后台管理页面加载资源(如果需要)
// add_action( 'admin_enqueue_scripts', 'mfp_enqueue_admin_assets' );

Thực hiện một yêu cầu Ajax đơn giản

Ajax cho phép tương tác với máy chủ mà không cần phải làm mới trang web. WordPress có bộ xử lý Ajax tích hợp sẵn.

Máy chủ chia sẻ của InterServer
Lưu trữ chia sẻ với mức phí $2,50 USD mỗi tháng, giảm giá $0,1 USD trong tháng đầu tiên, mã giảm giá tryinterserver, với 461 ứng dụng đám mây và cài đặt chỉ bằng một cú nhấp chuột.

Trước hết, trong tệp JavaScript ở phía trước (frontend): public-script.js Gửi yêu cầu từ Trung Quốc:

jQuery(document).ready(function($) {
    $('#my-button').on('click', function(e) {
        e.preventDefault();
        $.post(
            mfp_ajax_object.ajax_url, // WordPress 提供的 Ajax URL
            {
                action: 'mfp_get_server_time', // 触发的 PHP 钩子标识
                nonce: mfp_ajax_object.nonce, // 安全随机数
            },
            function(response) {
                if (response.success) {
                    $('#result-container').html('服务器时间:' + response.data);
                } else {
                    alert('请求失败:' + response.data);
                }
            }
        );
    });
});

Sau đó, xử lý yêu cầu này ở phía PHP. Cần phải có các hàm xử lý đăng ký riêng biệt (hoặc cùng lúc) cho người dùng đã đăng nhập và người dùng chưa đăng nhập.

// 处理 Ajax 请求的函数
function mfp_ajax_get_server_time() {
    // 验证 nonce,防止 CSRF 攻击
    check_ajax_referer( 'mfp_ajax_nonce', 'nonce' );

// 处理逻辑
    $server_time = current_time( 'mysql' );

// 返回成功响应(JSON 格式)
    wp_send_json_success( $server_time );
}
// 为登录用户注册处理函数
add_action( 'wp_ajax_mfp_get_server_time', 'mfp_ajax_get_server_time' );
// 为未登录用户注册处理函数(如果功能允许)
add_action( 'wp_ajax_nopriv_mfp_get_server_time', 'mfp_ajax_get_server_time' );

Chuẩn bị Quốc tế hóa và Phát hành Plugin

Để plugin của bạn có thể được sử dụng bởi người dùng WordPress trên toàn thế giới, việc hỗ trợ nhiều ngôn ngữ (internationalization – i18n) là một bước không thể thiếu. Đồng thời, việc thực hiện các bài kiểm thử kỹ lưỡng và tối ưu hóa trước khi phát hành cũng vô cùng quan trọng.

Sử dụng hàm gettext để thực hiện việc dịch văn bản.

WordPress sử dụng framework GNU gettext để thực hiện công việc dịch thuật. Bạn cần phải bao bọc tất cả các chuỗi ký tự dành cho người dùng bằng các hàm cụ thể.

Hãy sửa đổi hàm mã ngắn trước đó để nó hỗ trợ việc dịch văn bản.

function mfp_greeting_shortcode_i18n( $atts ) {
    $atts = shortcode_atts( array(
        'name' =&gt; __( '访客', 'my-first-plugin' ), // 默认值也可翻译
    ), $atts, 'mfp_greeting' );

// 使用 sprintf 和 __ 函数组合翻译字符串
    return '<p>' . sprintf( __( '你好,%s!欢迎使用我的第一个插件。', 'my-first-plugin' ), esc_html( $atts['name'] ) ) . '</p>'php
add_shortcode('mfp_greeting', 'mfp_greeting_shortcode_i18n');

Bạn cần sử dụng các công cụ như Poedit để quét toàn bộ các đoạn mã tương tự trong plugin. __(‘文本’, ‘my-first-plugin’) chuỗi, tạo ra .pot Đầu tiên, tạo ra tệp tin mẫu (template file), sau đó tạo ra các phiên bản tương ứng của tệp tin đó cho mỗi ngôn ngữ (chẳng hạn như tiếng Trung). .po và đã biên dịch .mo Tệp tin, và đặt nó vào… /languages Mục lục.

Tiến hành các bài kiểm thử cuối cùng và dọn dẹp mã nguồn (code cleaning).

Trước khi phát hành plugin, vui lòng thực hiện các kiểm tra sau:
1. **Kiểm thử chức năng:** Kích hoạt plugin trên một phiên bản WordPress mới, và kiểm tra xem tất cả các chức năng (shortcode, cài đặt, Ajax, v.v.) có hoạt động đúng như mong đợi hay không.
2. Kiểm tra mã nguồn: Đảm bảo rằng tất cả các dữ liệu đầu vào từ người dùng đều được xử lý một cách an toàn và đúng cách. esc_html, esc_attr, wp_kses_post Các hàm như này được sử dụng để thực hiện việc đánh dấu an toàn (safety escaping) dữ liệu. Liệu tất cả các truy vấn cơ sở dữ liệu đều sử dụng chúng hay không? $wpdb Các lớp thực hiện các câu lệnh chuẩn bị nhằm ngăn chặn tấn công SQL injection.
3. Kiểm tra hiệu năng: Đảm bảo rằng các script và định dạng (styles) chỉ được tải vào những trang cần thiết (có thể sử dụng các thẻ điều kiện như…) is_admin(), is_single() Thực hiện các phép đánh giá cần thiết. Tránh thực hiện các truy vấn cơ sở dữ liệu không cần thiết mỗi khi trang được tải.
4. Dọn dẹp tệp tin: Xóa các đoạn mã dùng để gỡ lỗi trong quá trình phát triển, các chú thích thừa thãi, và các tệp tin không còn được sử dụng nữa.
5. Tệp README: Tạo một tệp README chi tiết readme.txt Tệp tin này phải tuân thủ định dạng yêu cầu của WordPress.org, bao gồm phần mô tả, hướng dẫn cài đặt, các câu hỏi thường gặp, v.v. Đây là tệp tin bắt buộc để gửi plugin lên thư mục chính thức của WordPress.

Tóm lại

Thông qua hướng dẫn này, bạn đã hoàn thành quá trình chuyển đổi từ một tệp tin trống thành một plugin WordPress hoàn chỉnh, với các tính năng như mã ngắn (shortcodes), cấu hình nền (backend settings), tải tài nguyên front-end, tương tác Ajax và hỗ trợ đa ngôn ngữ (internationalization). Các bước chính bao gồm: thiết lập môi trường và tạo tệp chính chứa các tiêu đề chuẩn (standard headers); sử dụng các hook hành động (action hooks) và hook lọc (filter hooks) để tích hợp các chức năng mới; quản lý an toàn các tệp tài nguyên; thực hiện giao tiếp đồng bộ giữa phía front-end và back-end; và chuẩn bị cho việc dịch và kiểm thử trước khi phát hành plugin trên toàn cầu. Hãy nhớ rằng: bảo mật (định dạng dữ liệu, xác thực người dùng, sử dụng các mã nonce), hiệu năng (tải tài nguyên theo nhu cầu), và tuân thủ các tiêu chuẩn của WordPress (coding standards) là ba trụ cột cơ bản trong việc phát triển các plugin chất lượng cao. Việc tiếp tục học hỏi và thực hành các API nâng cao như tạo loại bài viết tùy chỉnh (custom article types), REST API, và công cụ chỉnh sửa nội dung (Blocks editor) sẽ giúp plugin của bạn trở nên mạnh mẽ hơn.

FAQ 常见问题

Phải chăng việc phát triển plugin luôn yêu cầu sử dụng lập trình hướng đối tượng (Object-Oriented Programming – OOP) không?

Không nhất thiết phải như vậy. Đối với các plugin đơn giản, việc sử dụng lập trình thủ tục (một tập hợp các hàm) hoàn toàn khả thi và còn đơn giản, trực quan hơn nữa. Tuy nhiên, đối với các plugin có quy mô lớn và phức tạp, việc áp dụng lập trình hướng đối tượng (OOP) cùng cấu trúc lớp sẽ giúp tổ chức mã nguồn tốt hơn, thực hiện được việc đóng gói (encapsulation) và tái sử dụng (reuse) các thành phần mã, đồng thời giảm thiểu tình trạng xung đột tên gọi (

Làm thế nào để gỡ lỗi các vấn đề trong plugin WordPress?

Trước hết, hãy đảm bảo rằng… wp-config.php trong tệp WP_DEBUGWP_DEBUG_LOG Hãy sử dụng một hằng số; như vậy, thông báo lỗi sẽ được ghi lại. /wp-content/debug.log Trong tệp tin, nội dung đó sẽ không được hiển thị cho người dùng. Thứ hai, có thể sử dụng… error_log() Hàm ghi giá trị biến ra log (nhật ký). Đối với Ajax hoặc các logic phức tạp, các panel “Mạng” (Network) và “Console” trong công cụ phát triển trình duyệt là những công cụ gỡ lỗi không thể thiếu.

Làm thế nào để plugin của tôi tương thích với giao diện (theme) và các plugin khác?

Các thực hành tốt nhất để duy trì tính tương thích là: tuân thủ nghiêm ngặt API chính thức của WordPress và các tiêu chuẩn lập trình; đặt một tiền tố duy nhất cho tên các hàm, lớp, và hook hành động của bạn (như đã đề cập trước đó). mfp_Để tránh xung đột, hãy kiểm tra xem các biến hoặc hàm toàn cục có tồn tại hay không trước khi sử dụng chúng. function_exists()class_exists()Và hãy giải thích rõ ràng trong tài liệu về các bảng cơ sở dữ liệu được tạo ra bởi plugin của bạn.选项用户元数据

Để gửi một plugin lên thư mục WordPress.org, bạn cần đáp ứng một số điều kiện sau:

Bạn cần có một tài khoản WordPress.org và đảm bảo plugin tuân thủ đầy đủ các yêu cầu chính thức. Điều này bao gồm: mã nguồn tuân thủ giấy phép tương thích GPL (thường là GPLv2+); plugin phải 100% mã nguồn mở và không phụ thuộc vào dịch vụ trả phí bên ngoài để chạy các chức năng cốt lõi; chứa định dạng tiêu chuẩn của readme.txt Tệp tin và mã nguồn không chứa bất kỳ nội dung độc hại hay không mong muốn nào; đồng thời đã qua kiểm tra bởi đội ngũ kiểm duyệt thủ công. Trước khi gửi lên, vui lòng đọc kỹ hướng dẫn phát triển plugin chính thức và hướng dẫn gửi bản cập nhật.