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ủa bạn, một trình soạn thảo mã, và kiến thức cơ bản về PHP. Chúng tôi khuyên bạn nên sử dụng XAMPP, MAMP hoặc Local by Flywheel để nhanh chóng thiết lập môi trường WordPress trên máy tính. Hãy đảm bảo rằng phiên bản PHP bạn đang sử dụng phù hợp với yêu cầu của WordPress; thông thường, phiên bản PHP 7.4 hoặc cao hơn được khuyến nghị.
Một plugin về bản chất là một hoặc nhiều tệp PHP, được đặt trong thư mục của WordPress.wp-content/pluginsCác plugin đều nằm trong thư mục tương ứng. Mỗi plugin phải có một tên duy nhất, và phần đầu của tệp chính (main file) của nó cần chứa các ghi chú thông tin tiêu chuẩn về plugin; đây là cơ sở để WordPress nhận diện các plugin.
Tạo tệp plugin đầu tiên của bạn
Đầu tiên, trongwp-content/pluginscủa bạn, ví dụmy-first-pluginSau đó, hãy tạo tập tin PHP chính bên trong thư mục đó; tên của tập tin này thường trùng với tên của thư mục đó.my-first-plugin.phpTrong tệp này, bạn cần viết thông tin về phần đầu của plugin (plugin header information).
<?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
*/ Sau khi lưu file, hãy truy cập trang “Plugins” (Các tiện ích mở rộng) trong giao diện quản trị WordPress. Bạn sẽ thấy “My First Plugin” xuất hiện trong danh sách các tiện ích mở rộng. Hãy kích hoạt nó. Mặc dù hiện tại tiện ích này chưa có bất kỳ chức năng nào, điều này chứng tỏ rằng tiện ích của bạn đã được WordPress tải thành công.
Hiểu rõ cơ chế cốt lõi của WordPress: Hook và Filter
Sức mạnh về khả năng mở rộng của WordPress bắt nguồn từ kiến trúc dựa trên các sự kiện (event-driven architecture), trong đó yếu tố then chốt là hệ thống “Hook” (Câu khóa). Có hai loại Hook chính: Action (Hành động) và Filter (Bộ lọc). Việc hiểu rõ về chúng là yếu tố then chốt để bạn có thể phát triển các plugin một cách hiệu quả.
Các “hook hành động” (action hooks) cho phép bạn chèn và thực thi đoạn mã của riêng mình vào những thời điểm cụ thể, chẳng hạn như khi bài viết được đăng lên hoặc khi trang web được tải. Ví dụ, bạn có thể gửi một email khi một bài viết được đăng. Bạn có thể sử dụng chúng để tự động thực hiện các tadd_action()Hàm này sẽ gắn (mount) hàm tùy chỉnh của bạn vào hook hành động (action hook) được chỉ định.
Các hook (móc) của bộ lọc cho phép bạn thay đổi dữ liệu. Trước khi dữ liệu được sử dụng (chẳng hạn như lưu vào cơ sở dữ liệu hoặc hiển thị trên trình duyệt), bạn có thể chặn nó lại và chỉnh sửa nó. Ví dụ, bạn có thể thay đổi tiêu đề bài viết hoặc nội dung bình luận. Bạn có thể sử dụng các hook này để thực hiện các thao tác cầnadd_filter()Hàm được sử dụng để áp dụng bộ lọc (filter).
Sử dụng action hook để thêm tính năng
Giả sử chúng ta muốn thêm một dòng văn bản tùy chỉnh vào phần chân trang (footer) của trang quản trị trang web. WordPress cung cấp một công cụ có tên là…admin_footerĐây là đoạn mã dùng để thiết lập các “hook” (các điểm kết nối) cho các hành động cụ thể trong ứng dụng. Chúng ta có thể thêm đoạn mã sau vào tệp chính của plugin:
Đọc thêm Hướng dẫn bắt đầu phát triển plugin WordPress: Xây dựng plugin chức năng đầu tiên của bạn từ đầu。
// 定义一个在管理后台页脚显示信息的函数
function myplugin_display_admin_footer_text() {
echo '<p>Cảm ơn bạn đã sử dụng “Plugin Đầu Tiên Của Tôi”!</p>';
}
// 将函数挂载到 admin_footer 动作钩子
add_action( 'admin_footer', 'myplugin_display_admin_footer_text' ); Hãy lưu file và làm mới trang quản trị WordPress. Sau đó, cuộn xuống phần chân trang (footer) – bạn sẽ thấy đoạn văn bản vừa được thêm vào. Đó chính là cách sử dụng cơ bản của các “action hook”: thực thi đoạn mã ở một vị trí cụ thể trong trang web.
Sử dụng bộ lọc để chỉnh sửa nội dung.
Bây giờ, hãy thử sửa đổi tiêu đề của tất cả các bài viết bằng cách thêm một ký hiệu thương hiệu vào cuối mỗi tiêu đề. Chúng ta có thể sử dụng…the_titleBộ lọc.
// 定义一个修改文章标题的函数
function myplugin_modify_post_title( $title, $post_id ) {
// 确保只在主循环且非管理后台中修改
if ( ! is_admin() && in_the_loop() ) {
$title = $title . ' ™';
}
return $title;
}
// 将函数挂载到 the_title 过滤器钩子,参数2表示接受2个参数
add_filter( 'the_title', 'myplugin_modify_post_title', 10, 2 ); Đoạn mã này sẽ kiểm tra xem môi trường hiện tại có đang trong vòng lặp chính của bài viết ở phía trước (frontend) hay không. Nếu có, nó sẽ thêm ký hiệu “™” sau tiêu đề của bài viết.10là mức độ ưu tiên (số càng nhỏ càng thực thi trước),2Điều này có nghĩa là hàm của chúng ta nhận hai tham số (dữ liệu nguyên bản).$title和$post_id)。
Xây dựng chức năng plugin: Tạo menu quản lý và trang cấu hình
Một plugin trưởng thành thường cần cung cấp các tùy chọn cấu hình trong giao diện quản trị của WordPress. Điều này đòi hỏi phải tạo ra một trang menu quản lý riêng biệt dành cho plugin đó. WordPress cung cấp nhiều hàm API phong phú để thực hiện chức năng này. Ví dụ:add_menu_page()和add_options_page()。
thêm menu quản lý cấp cao nhất
Chúng tôi sẽ thêm một menu độc lập ở cấp độ cao nhất cho plugin này. Điều này thường được thực hiện trong quá trình phát triển phần mềm, nhằm tạo sự thuận tiện cho người dùng khi sử dụng plugin.admin_menuViệc này được thực hiện trong các “action hook”. Chúng ta sẽ tạo một hàm để định nghĩa menu và các trang (pages).
// 定义添加管理菜单的函数
function myplugin_add_admin_menu() {
add_menu_page(
'我的插件设置', // 页面标题
'我的插件', // 菜单标题
'manage_options', // 所需权限(管理员)
'myplugin-settings-page', // 菜单slug(唯一标识)
'myplugin_display_settings_page', // 用于显示页面内容的回调函数
'dashicons-admin-generic', // 菜单图标(Dashicons)
30 // 菜单位置
);
}
// 将函数挂载到 admin_menu 钩子
add_action( ‘admin_menu’, ‘myplugin_add_admin_menu’ ); Tiếp theo, chúng ta cần định nghĩa hàm gọi lại (callback function).myplugin_display_settings_page()Đây là đoạn mã HTML dùng để hiển thị trang cấu hình (setting page).
// 定义设置页面的显示内容
function myplugin_display_settings_page() {
?>
<div class="wrap">
<h1>Cài đặt plugin của tôi</h1>
<form method="post" action="/vi/options.php/" data-trp-original-action="options.php">
<?php
// 输出设置字段、安全nonce等
settings_fields( ‘myplugin_settings_group’ );
do_settings_sections( ‘myplugin-settings-page’ );
submit_button();
?>
<input type="hidden" name="trp-form-language" value="vi"/></form>
</div>
<?php
} Cài đặt đăng ký, trường dữ liệu và phân vùng (Registration settings, Fields, and Partitioning)
Để xử lý dữ liệu từ biểu mẫu một cách an toàn, chúng ta cần sử dụng API cấu hình của WordPress. Điều này bao gồm việc đăng ký các cấu hình mới, thêm các phân vùng (sections) và trường (fields) cho các cấu hình đó.
// 初始化插件设置
function myplugin_settings_init() {
// 1. 注册一个设置(存储在wp_options表中)
register_setting(
‘myplugin_settings_group’, // 设置组名,与 settings_fields() 对应
‘myplugin_options’ // 存储在数据库中的选项名
);
// 2. 添加一个设置分区
add_settings_section(
‘myplugin_section_basic’, // 分区ID
‘基础设置’, // 分区标题
‘myplugin_section_basic_callback’, // 分区介绍的回调函数
‘myplugin-settings-page’ // 所属页面的slug
);
// 3. 为分区添加一个字段
add_settings_field(
‘myplugin_field_message’, // 字段ID
‘欢迎信息’, // 字段标签
‘myplugin_field_message_callback’, // 渲染字段HTML的回调函数
‘myplugin-settings-page’, // 所属页面的slug
‘myplugin_section_basic’ // 所属分区的ID
);
}
add_action( ‘admin_init’, ‘myplugin_settings_init’ );
// 分区介绍的回调函数
function myplugin_section_basic_callback() {
echo ‘<p>Cấu hình thông tin cơ bản cho plugin.</p>’;
}
// 字段渲染的回调函数
function myplugin_field_message_callback() {
// 从数据库获取现有值
$options = get_option( ‘myplugin_options’ );
$value = $options[‘message’] ?? ‘’; // PHP 7.0+ 空合并运算符
// 输出输入框
echo ‘<input type="“text”" name="“myplugin_options[message]”" value="“‘" . esc_attr( $value ) ‘” class ="“regular-text”" />‘;
} Bây giờ, plugin của bạn đã có một trang cài đặt quản lý hoàn chỉnh và tuân thủ các tiêu chuẩn của WordPress, cho phép bạn lưu trữ và đọc các tùy chọn cấu hình một cách an toàn.
Các thực hành tốt nhất cho việc quốc tế hóa và bảo mật các plugin
Để plugin của bạn có thể được người dùng trên toàn thế giới sử dụng, việc hỗ trợ nhiều ngôn ngữ (internationalization – i18n) là một bước không thể thiếu. Đồng thời, tuân thủ các quy định bảo mật là nền tảng cơ bản để bảo vệ bạn và trang web của người dùng khỏi các cuộc tấn công.
Thực hiện quốc tế hóa văn bản (text internationalization)
Sử dụng WordPress__()、_e()Bạn có thể sử dụng các hàm như `translate()` để thực hiện việc dịch. Đầu tiên, bạn cần đảm bảo rằng đã thiết lập đúng cách các thông tin cần thiết ở phần đầu của plugin (header của plugin).Text Domain(Ví dụ:my-first-pluginSau đó, hãy bao bọc tất cả các chuỗi dữ liệu dành cho người dùng bằng hàm dịch.
// 在插件代码中,将硬编码的文本替换
// 修改前:echo ‘<p>Cảm ơn bạn đã sử dụng “Plugin Đầu Tiên Của Tôi”!</p>’;
// 修改后:
function myplugin_display_admin_footer_text() {
echo ‘<p>‘ . esc_html__( ‘感谢使用“我的第一个插件”!’, ‘my-first-plugin’ ) . ‘</p>’;
} Tiếp theo, bạn cần sử dụng các công cụ như Poedit để tạo ra (hoặc thực hiện các thao tác cần thiết)….pot(Template) file, placed in the plugin.languagesNó nằm trong thư mục. Người dịch có thể tạo tài liệu tương ứng..povà đã biên dịch.moFile. Cuối cùng, hãy sử dụng nó khi khởi tạo plugin.load_plugin_textdomain().
function myplugin_load_textdomain() {
load_plugin_textdomain( ‘my-first-plugin’, false, dirname( plugin_basename( __FILE__ ) ) . ‘/languages/’ );
}
add_action( ‘plugins_loaded’, ‘myplugin_load_textdomain’ ); Tuân theo các quy tắc mã hóa an toàn
An toàn là yếu tố quan trọng nhất. Trước hết, đừng bao giờ tin tưởng vào những dữ liệu do người dùng nhập vào. Mọi dữ liệu đến từ người dùng hoặc các nguồn bên ngoài (chẳng hạn như…)$_GET, $_POST, $_COOKIETất cả các dữ liệu đều phải trải qua quá trình xác thực, làm sạch và mã hóa (escape).
- Khi xuất dữ liệu sang HTML, JavaScript hoặc URL, hãy sử dụng các hàm mã hóa (escape functions) tương ứng.
// 输出到HTML属性
echo ‘<input value="“‘" . esc_attr( $value ) ‘“ />‘;
// 输出到HTML内容
echo ‘<p>‘ . esc_html( $text ) . ‘</p>’;
// 输出到JavaScript变量
echo ‘<script>var msg = “‘ . esc_js( $message ) . ‘“;</script>’;
// 输出到URL
echo ‘<a href="/vi/“‘/" . esc_url( $url ) ‘“>Liên kết</a>’; - Xác minh đầu vào: Kiểm tra xem dữ liệu có đúng định dạng dự kiến hay không (ví dụ: có phải là email, số, v.v.).
if ( ! filter_var( $email, FILTER_VALIDATE_EMAIL ) ) {
// 不是有效的邮箱地址
wp_die( ‘无效的邮箱格式。’ );
} - Kiểm tra quyền hạn: Trước khi thực hiện các thao tác quản lý, hãy kiểm tra xem người dùng hiện tại có đủ quyền hạn cần thiết hay không.
if ( ! current_user_can( ‘manage_options’ ) ) {
wp_die( ‘你没有执行此操作的权限。’ );
} - Xác minh Nonce: Đối với các thao tác liên quan đến thay đổi trạng thái (như gửi biểu mẫu, yêu cầu AJAX), sử dụng Nonce (số một lần) để ngăn chặn tấn công giả mạo yêu cầu chéo trang (CSRF).
// 在表单中输出nonce字段
wp_nonce_field( ‘myplugin_action’, ‘myplugin_nonce’ );
// 在处理请求时验证nonce
if ( ! isset( $_POST[‘myplugin_nonce’] ) || ! wp_verify_nonce( $_POST[‘myplugin_nonce’], ‘myplugin_action’ ) ) {
wp_die( ‘安全校验失败。’ );
} Tóm lại
Thông qua hướng dẫn này, bạn đã hoàn thành toàn bộ quá trình từ việc tạo ra các tệp tin plugin cơ bản, hiểu và sử dụng hệ thống hook của WordPress, xây dựng giao diện quản trị nền tảng, cho đến việc triển khai các tính năng hỗ trợ đa ngôn ngữ (internationalization) và áp dụng các biện pháp bảo mật cơ bản. Bạn đã nắm vững những kỹ năng cốt lõi cần thiết để phát triển một plugin WordPress với chức năng đầy đủ, cấu trúc rõ ràng, và độ bảo mật cao. Bí quyết của việc phát triển plugin nằm ở việc tận dụng tối đa các hook (action và filter) để mở rộng chức năng của WordPress, đồng thời luôn đặt yếu tố bảo mật và khả năng bảo trì lên hàng đầu. Tiếp theo, bạn có thể thử khám phá các API phức tạp hơn như các bảng cơ sở dữ liệu tùy chỉnh, tương tác AJAX, hoặc các điểm cuối (endpoint) của REST API để xây dựng những công cụ mạnh mẽ hơn.
FAQ 常见问题
Để phát triển một plugin cho WordPress với tên ###, bạn cần có những kiến thức cơ bản sau:
Bạn cần có kiến thức cơ bản về lập trình PHP; việc hiểu biết về HTML, CSS và JavaScript (đặc biệt là jQuery) cũng sẽ rất hữu ích. Điều quan trọng nhất là bạn cần có cái nhìn tổng quan về cấu trúc cơ bản của WordPress, bao gồm các khái niệm như theme (giao diện), plugin (tiện ích mở rộng), loại bài viết, vai trò người dùng, v.v. Hướng dẫn này giả định rằng bạn đã nắm vững những kiến thức cơ bản này.
Làm thế nào để gỡ lỗi plugin WordPress của tôi?
Trước hết, hãy đảm bảo rằng bạn đã…wp-config.phptrong tệpWP_DEBUGHằng số được thiết lậptrueĐiều này sẽ hiển thị các lỗi PHP, cảnh báo và thông báo trên trang web. Thứ hai, bạn có thể sử dụng…error_log()Hàm này sẽ ghi thông tin gỡ lỗi vào nhật ký lỗi của máy chủ. Đối với các công việc gỡ lỗi phức tạp hơn, bạn có thể xem xét sử dụng các tiện ích gỡ lỗi chuyên dụng như Query Monitor, vốn cho phép theo dõi chi tiết các thao tác như truy vấn cơ sở dữ liệu, việc thực thi các đoạn mã (hook), quá trình tải các tập tin script, v.v.
Làm thế nào để tôi phân phối các plugin mà tôi đã phát triển?
Đối với mục đích sử dụng cá nhân hoặc chia sẻ trên phạm vi hẹp, bạn có thể đơn giản gói file thành định dạng ZIP. Nếu bạn muốn phát hành công khai, có hai cách chính: thứ nhất là nộp plugin đó vào danh mục plugin chính thức của WordPress (WordPress.org); điều này đòi hỏi bạn phải tuân thủ các hướng dẫn và tiêu chuẩn mã nguồn của họ, nhưng bạn sẽ nhận được sự quảng bá rộng rãi nhất; thứ hai là phân phối qua trang web của riêng mình hoặc các nền tảng thương mại bên thứ ba như CodeCanyon. Trước khi nộp plugin vào danh mục chính thức, hãy đảm bảo rằng chất lượng và tính bảo mật của mã nguồn là tốt nhất.
Làm thế nào để thêm loại bài viết tùy chỉnh hoặc hệ thống phân loại cho plugin của tôi?
Bạn có thể sử dụngregister_post_type()Hàm được sử dụng để tạo loại bài viết tùy chỉnh (Custom Post Type – CPT).register_taxonomy()Các hàm được sử dụng để tạo ra các hệ thống phân loại tùy chỉnh. Những thao tác này tốt nhất nên được thực hiện trong…initCác thao tác được thực hiện trong các “hook” (khung lập trình được định nghĩa sẵn trong WordPress). Trong WordPress Codex và Developer Handbook có các hướng dẫn chi tiết về các tham số của hai hàm này; đây là cách mạnh mẽ để mở rộng khả năng quản lý nội dung của WordPress.
Làm thế nào để tránh xung đột tên hàm trong các plugin?
Để tránh xung đột giữa các tên hàm, tên lớp hoặc tên hằng số, thực hành tốt nhất là sử dụng không gian tên (namespace) trong PHP 5.3 trở lên. Nếu plugin của bạn cần hỗ trợ các phiên bản PHP cũ hơn, hoặc bạn muốn đảm bảo tính tương thích cao nhất, bạn có thể thêm một tiền tố duy nhất cho tất cả các định danh. Ví dụ, bạn có thể sử dụng tên plugin hoặc tên viết tắt làm tiền tố.myplugin_function_name、MyPlugin_ClassName或MYPLUGIN_CONSTANTCác đoạn mã ví dụ trong hướng dẫn này đều sử dụng phương pháp đặt tiền tố (prefixing).
Bước tiếp theo, chúng ta nên làm gì tiếp theo?
Đọc thêm và kiến thức thực tế
Những nội dung sau đây liên quan đến chủ đề của bài viết này, thích hợp để tiếp tục đọc sâu hơn. Ưu tiên bắt đầu với bài viết gần nhất với vấn đề hiện tại của bạn, rồi dần dần mở rộng sang các chủ đề xung quanh, hiệu quả thường sẽ tốt hơn.
- Lời nói đầu: Tại sao chọn WordPress để phát triển?
- Tại sao bạn chọn WooCommerce làm giải pháp thương mại điện tử cho doanh nghiệp của mình?
- Hướng dẫn Toàn diện WooCommerce: Xây dựng Cửa hàng Trực tuyến và Chiến lược Bán hàng Từ Con số 0
- Hướng dẫn toàn diện về việc phát triển giao diện WordPress: Xây dựng trang web chuyên nghiệp từ con số không
- 10 Tiện ích WordPress Thiết Yếu Giúp Nâng Cao Hiệu Suất Và Bảo Mật Trang Web Một Cách Toàn Diện