Cấu trúc cơ bản của một plugin WordPress
Một plugin chuẩn của WordPress có cốt lõi là một thành phần được đặt tại… /wp-content/plugins/ Đây là một thư mục độc lập nằm trong thư mục chính. Bên trong thư mục này, phải có ít nhất một tệp PHP chính; phần ghi chú ở đầu tệp này chứa thông tin meta về plugin, và đây chính là cơ sở để WordPress nhận diện plugin đó.
Các ghi chú ở phần đầu của plugin rất quan trọng. Chúng sử dụng một định dạng cụ thể để thông báo cho hệ thống WordPress về tên plugin, mô tả, phiên bản, tác giả và các thông tin khác. Một ví dụ điển hình về ghi chú ở phần đầu của plugin như sau:
<?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
*/ Đoạn mã này phải được đặt ở đầu tệp chính của plugin. Trong đó,Plugin Name Những trường được đánh dấu là bắt buộc phải điền; các trường còn lại đều là tùy chọn. Khi WordPress quét thư mục các plugin, nó sẽ sử dụng những thông tin này để hiển thị danh sách các plugin trên giao diện quản trị nền.
Ngoài tệp chính, một plugin đầy đủ chức năng thường còn bao gồm các tệp và thư mục khác, chẳng hạn như những thư mục dùng để lưu trữ các tài nguyên JavaScript và CSS. assets Thư mục, được sử dụng cho công việc dịch thuật. languages Thư mục dùng để chứa các tệp lớp (class files). includes Các thư mục, cùng với các tệp mẫu dùng để hiển thị trên giao diện người dùng (frontend), đều rất quan trọng. Một cấu trúc thư mục được thiết kế tốt là nền tảng vững chắc cho khả năng bảo trì và mở rộng của các plugin.
Hiểu rõ cơ chế cốt lõi của WordPress: Các hook (khớp nối)
Triết lý cốt lõi của việc phát triển plugin cho WordPress là “hook (khớp nối) và callback (hàm gọi lại)”. Các hook cho phép nhà phát triển chèn đoạn mã tùy chỉnh của mình vào những thời điểm nhất định trong quá trình thực thi mã nguồn gốc của WordPress, từ đó có thể sửa đổi hoặc nâng cấp các chức năng mặc định mà không cần phải thay đổi trực tiếp các tệp mã nguồn gốc. Điều này giúp đảm bảo tính nguyên vẹn của mã nguồn gốc và an toàn khi cập nhật plugin.
Các hook chủ yếu được chia thành hai loại: hook hành động (action hook) và hook bộ lọc (filter hook).
Cách sử dụng hook hành động (Action Hook)
Các “action hook” được thực thi khi một sự kiện cụ thể xảy ra, chẳng hạn như việc đăng bài, tải trang quản lý, hoặc người dùng đăng nhập. Chúng không yêu cầu trả về bất kỳ giá trị nào, mà chủ yếu được sử dụng để thực hiện một số thao tác nhất định. Các nhà phát triển thường sử dụng chú add_action() Hàm này sẽ gắn (mount) hàm tùy chỉnh (hàm gọi lại – callback function) vào hook hành động (action hook) được chỉ định.
Ví dụ, nếu chúng ta muốn tự động thêm một đoạn thông báo bản quyền vào cuối mỗi bài viết, chúng ta có thể sử dụng công cụ này. the_content Đây là một “hook hành động” (action hook) – mặc dù nó thường được sử dụng như một bộ lọc (filter), nhưng ở đây chúng ta đang minh họa khái niệm về các hành động (actions). Một ví dụ điển hình là việc thực hiện một thao tác nào đó khi WordPress được khởi động (initiated).
function myplugin_setup() {
// 初始化插件,例如创建数据库表
}
add_action( 'init', 'myplugin_setup' ); Đoạn mã trên cho thấy rằng, khi WordPress thực hiện đến… init Khi thực hiện hành động này, những thứ mà chúng ta đã định nghĩa sẽ được chạy đồng thời. myplugin_setup Hàm.
Cách sử dụng các hook của bộ lọc (Filter Hooks)
Các hook của bộ lọc (filter hooks) được sử dụng để thay đổi dữ liệu. Chúng nhận một biến đầu vào và trả về biến đã được sửa đổi. Các nhà phát triển thường sử dụng chúng trong quá trình xử lý dữ liệu. add_filter() Đây là một hàm được sử dụng để gắn các hàm lọc tùy chỉnh. Đây là phương thức phổ biến nhất để thay đổi nội dung bài viết, tiêu đề, liên kết, và các dữ liệu khác.
Theo ví dụ trên, cách thực hiện đúng đắn nhất để thêm thông tin bản quyền vào nội dung bài viết là sử dụng định dạng sau: the_content bộ lọc:
function myplugin_add_copyright( $content ) {
if ( is_single() ) {
$content .= '<p>Bản quyền của bài viết này thuộc về trang web này. Khi sao chép, vui lòng ghi rõ nguồn gốc.</p>';
}
return $content;
}
add_filter( 'the_content', 'myplugin_add_copyright' ); Trong ví dụ này, hàm… myplugin_add_copyright Nhận được dữ liệu nguyên thủy. $content Biến đó chứa một đoạn văn bản HTML; sau đó, đoạn văn bản này được thêm vào cuối biến đó, và nội dung đã được sửa đổi được trả về. WordPress sẽ sử dụng giá trị được trả về này thay thế cho nội dung ban đầu để hiển thị trên trang web.
tạo trang quản lý plugin
Nhiều plugin yêu cầu có các tùy chọn cấu hình trong giao diện quản trị của WordPress, và điều này đòi hỏi phải tạo ra các trang quản lý riêng. WordPress cung cấp một loạt hàm để thêm các mục menu chính hoặc menu con.
Thêm mục menu cấp cao
Sử dụng add_menu_page() Hàm này có thể tạo một menu nền tảng độc lập cho plugin. Hàm yêu cầu nhiều tham số, bao gồm tiêu đề trang, tiêu đề menu, quyền truy cập, tên biệt danh của menu, hàm gọi lại (callback function), v.v.
Dưới đây là một ví dụ mã nguồn để tạo trang quản trị cấp cao đơn giản:
function myplugin_add_admin_menu() {
add_menu_page(
'我的插件设置', // 页面标题
'我的插件', // 菜单标题
'manage_options', // 所需权限(管理员)
'myplugin-settings', // 菜单别名(URL中的slug)
'myplugin_settings_page', // 用于输出页面内容的回调函数
'dashicons-admin-generic', // 菜单图标(使用Dashicons)
30 // 菜单位置
);
}
add_action( 'admin_menu', 'myplugin_add_admin_menu' );
// 定义输出页面内容的回调函数
function myplugin_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
settings_fields( 'myplugin_settings_group' );
do_settings_sections( 'myplugin-settings' );
submit_button();
?>
<input type="hidden" name="trp-form-language" value="vi"/></form>
</div>
<?php
} Đoạn mã này trước tiên thực hiện… add_action Thêm hàm quản lý menu vào (mount the menu management function to)… admin_menu “Hook.” Khi phần backend tải danh mục (menu) vào hệ thống, đoạn mã liên quan đến “hook” này sẽ được thực thi. myplugin_add_admin_menuHãy đăng ký một menu cấp cao mới có tên “Các tiện ích của tôi” (My Plugins). Sau khi nhấp vào menu này, WordPress sẽ thực hiện các thao tác cần thiết. myplugin_settings_page Hàm để render nội dung trang.
Thiết lập lưu trữ cho các trường dữ liệu và tùy chọn
Chỉ có cấu trúc ngoại vi của trang web là chưa đủ; chúng ta cần tạo các trường biểu mẫu trên trang và lưu trữ an toàn các giá trị mà người dùng nhập vào. API Settings của WordPress được thiết kế đặc biệt cho mục đích này, giúp tự động hóa quá trình xác thực dữ liệu, lưu trữ dữ liệu, và tạo các mã bảo mật (nonce).
Trước tiên, chúng ta cần đăng ký một tùy chọn cài đặt, một khối cấu hình, và các trường dữ liệu cụ thể:
function myplugin_settings_init() {
// 1. 注册一个设置选项到数据库
register_setting( 'myplugin_settings_group', 'myplugin_options' );
// 2. 在页面内添加一个设置区块
add_settings_section(
'myplugin_section_main',
'主要设置',
null,
'myplugin-settings'
);
// 3. 在区块内添加一个具体的字段
add_settings_field(
'myplugin_field_text',
'示例文本输入',
'myplugin_field_text_render', // 渲染字段HTML的回调函数
'myplugin-settings',
'myplugin_section_main'
);
}
add_action( 'admin_init', 'myplugin_settings_init' );
// 定义字段的HTML输出
function myplugin_field_text_render() {
$options = get_option( 'myplugin_options' );
$value = $options['text_field'] ?? '';
?>
<input type='text' name='myplugin_options[text_field]' value='<?php echo esc_attr( $value ); ?>'>
<?php
} Thông qua bộ API này, sau khi biểu mẫu được gửi đi, dữ liệu sẽ được tự động lưu trữ vào wp_options Trong bảng, cái được gọi là… myplugin_options Trong các bản ghi đó (một mảng được định dạng dưới dạng dữ liệu được sắp xếp theo thứ tự), các nhà phát triển có thể sử dụng chúng. get_option( ‘myplugin_options’ ) Hãy truy cập những giá trị này một cách an toàn, dù là ở phía trước (frontend) hay phía sau (backend).
Bảo mật và thực hành tốt nhất cho plugin
Việc phát triển một plugin được nhiều người yêu thích đòi hỏi phải chú trọng đến cả yếu tố bảo mật và chất lượng mã nguồn. Việc tuân thủ các thực hành tốt nhất (best practices) sẽ giúp giảm thiểu tối đa nguy cơ xuất hiện các lỗ hổng phổ biến và nâng cao trải nghiệm ng
Xác thực, thoát ký tự và làm sạch dữ liệu
Tất cả dữ liệu đến từ người dùng hoặc các nguồn bên ngoài đều không đáng tin cậy. Khi truyền dữ liệu đến trình duyệt (phía trước), cần phải thực hiện thao tác “escape” để ngăn chặn các cuộc tấn công kiểu cross-site scripting (XSS); khi lưu dữ liệu vào cơ sở dữ liệu (phía sau), cần phải làm sạch và xác thực dữ liệu đó trước khi lưu vào hệ thống.
WordPress cung cấp rất nhiều hàm hỗ trợ. Đối với nội dung được xuất ra dưới dạng HTML, bạn có thể sử dụng những hàm này để thực hiện các thao tác cần thiết. esc_html(), esc_attr(), esc_url() Các hàm như vậy. Đối với việc gán giá trị ra biến trong JavaScript, hãy sử dụng… wp_json_encode()Trong các thao tác trên cơ sở dữ liệu, bạn nên luôn sử dụng… $wpdb->prepare() Thực hiện truy vấn có tham số (parameterized query), hoặc sử dụng các công cụ như… sanitize_text_field(), intval() Các hàm như vậy được sử dụng để xử lý và làm sạch dữ liệu đầu vào.
// 不安全的做法
echo $_GET['user_input'];
// 安全的做法:输出到HTML内容
echo esc_html( $_GET['user_input'] );
// 安全的做法:用于HTML属性
$url = esc_url( $_GET['url'] );
echo "<a href='/vi/$url/'>Liên kết</a>";
// 安全的做法:清理后存入数据库
$clean_title = sanitize_text_field( $_POST['title'] );
update_post_meta( $post_id, ‘title’, $clean_title ); Chuẩn bị quốc tế hóa và bản địa hóa
Để plugin có thể được sử dụng bởi người dùng trên toàn thế giới, việc chuẩn bị cho hỗ trợ đa ngôn ngữ (internationalization) là rất cần thiết. Điều này có nghĩa là tất cả các chuỗi văn bản dành cho người dùng không được lưu trữ trực tiếp trong mã nguồn một cách cố định (hard-coded), mà phải được bao bọc bằng các hàm dịch
WordPress sử dụng framework GNU gettext. Trong mã nguồn của nó, framework này được áp dụng để hỗ trợ việc dịch nội dung. __() Vui lòng cung cấp đoạn văn bản bạn muốn dịch, và tôi sẽ thực hiện công việc dịch cho bạn. _e() Dịch và xuất chuỗi trực tiếp. Đồng thời, cần xác định trong phần chú thích đầu plugin Text DomainVà hãy sử dụng nó khi plugin được tải vào hệ thống. load_plugin_textdomain() Hàm này được sử dụng để tải các tệp dịch về.
// 定义可翻译的字符串
$greeting = __( ‘Hello, World!', ‘my-first-plugin’ );
_e( ‘Settings saved successfully!', ‘my-first-plugin’ );
// 在插件初始化时加载翻译
function myplugin_load_textdomain() {
load_plugin_textdomain( ‘my-first-plugin’, false, dirname( plugin_basename( __FILE__ ) ) . ‘/languages/’ );
}
add_action( ‘init’, ‘myplugin_load_textdomain’ ); Các nhà phát triển cần sử dụng các công cụ như Poedit để tạo ra những tài liệu cần thiết. .pot Đây là tệp mẫu dùng để những người dịch tạo ra các bản dịch bằng các ngôn ngữ khác nhau. .po và đã biên dịch .mo Các tệp ngôn ngữ đã được chuẩn bị sẵn cần được đặt trong thư mục của plugin. /languages/ Nằm trong thư mục này… Đây là bước quan trọng giúp plugin của chúng ta tiến ra thị trường quốc tế.
Tóm lại
Việc phát triển plugin cho WordPress là quá trình biến những ý tưởng sáng tạo thành những chức năng thực tế, và yếu tố then chốt nằm ở việc hiểu rõ và sử dụng thành thạo hệ thống hook (những điểm kết nối trong mã nguồn). Quá trình bắt đầu từ việc tạo một tệp chính (main file) có các chú thích đầu (header comments) đúng cách; sau đó, bạn can thiệp vào quy trình thực thi thông qua các hook hành động (action hooks) và điều chỉnh dữ liệu được hiển thị thông qua các hook lọc (filter hooks). Bạn có thể sử dụng API Settings của WordPress để tạo giao diện quản trị nền (backend administration interface) một cách an toàn và theo tiêu chuẩn. Việc tuân thủ nghiêm ngặt các quy tắc bảo mật (như xác thực dữ liệu, việc xử lý ký tự đặc biệt, và làm sạch dữ liệu) cùng các tiêu chuẩn quốc tế hóa là con đường bắt buộc để một plugin trở nên chín chắn, ổn định và được sử dụng rộng rãi. Hãy nhớ rằng, một plugin tốt không chỉ cần có chức năng mạnh mẽ mà còn phải đảm bảo an toàn, hiệu quả và dễ sử dụng đối với người dùng trên toàn thế giới.
FAQ 常见问题
Một plugin cần ít nhất bao nhiêu tệp tin?
Một plugin chỉ cần ít nhất một tệp PHP. Chỉ cần tệp này chứa các chú thích đầu tiên (header comments) đúng quy định của WordPress, và được đặt ở đúng vị trí… /wp-content/plugins/ Bạn chỉ cần đặt tệp tin đó vào thư mục chính của trang web (có thể đặt trực tiếp, hoặc vào một thư mục con), và WordPress sẽ tự động nhận diện và kích hoạt nó.
Làm thế nào để gỡ lỗi mã plugin của tôi?
It is recommended to use this in the development environment. wp-config.php Đặt giá trị của hằng số WP_DEBUG Hằng số được thiết lập trueĐồng thời, bạn có thể thực hiện việc thiết lập (set) các thông số cần thiết. WP_DEBUG_LOG vì trueGhi thông tin lỗi vào… /wp-content/debug.log Hãy tránh hiển thị nội dung tệp trực tiếp trên trang web. Ngoài ra, việc sử dụng công cụ phát triển trình duyệt (browser developer tools) để xem thông tin console và các yêu cầu mạng (network requests) cũng rất quan trọng.
Các tùy chọn của plugin nên được đặt ở đâu?
Đối với các thiết lập đơn giản dạng cặp khóa-giá trị (key-value pairs), chúng tôi khuyên mạnh bạn nên sử dụng API Options của WordPress. add_option(), update_option(), get_option() Các hàm thực hiện các thao tác cần thiết, và dữ liệu sẽ được lưu trữ một cách an toàn. wp_options Trong các bảng cơ sở dữ liệu, đối với lượng dữ liệu có cấu trúc lớn, bạn có thể xem xét việc tạo các bảng cơ sở dữ liệu tùy chỉnh. Tuy nhiên, điều này đòi hỏi quản lý vòng đời phức tạp hơn (tạo bảng khi cài đặt và xóa bảng khi gỡ cài đặt).
Làm thế nào để plugin của tôi tương thích với nhiều phiên bản WordPress hơn?
Trong quá trình phát triển, hãy tránh sử dụng những hàm quá mới mẻ và chỉ được hỗ trợ bởi các phiên bản WordPress cao cấp. Đối với những hàm mới mà bạn muốn sử dụng, hãy thử chúng trước khi áp dụng chúng vào dự án thực tế. function_exists() Kiểm tra và cung cấp các giải pháp thay thế (degradation solutions) một cách hiệu quả và thẩm mỹ. Điều này đặc biệt quan trọng đối với các plugin (phần mềm mở rộng). readme.txt Trong tệp tin có ghi rõ phiên bản WordPress tối thiểu mà các bài kiểm thử được coi là thành công. Việc thực hiện các bài kiểm thử định kỳ trên nhiều phiên bản khác nhau của WordPress là cách tốt nhất để đảm bảo tính tương thích giữa các phiên bản đó.
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.
- Hướng dẫn phát triển plugin WordPress: Từ con số không đến plugin tùy chỉnh đầu tiên của bạn
- Trở thành nhà phát triển plugin WordPress: Hướng dẫn toàn diện từ đầu đến cuối
- Hướng dẫn toàn diện phát triển plugin WordPress: Từ cơ bản đến chuyên sâu để tạo các tiện ích mở rộng chuyên nghiệp
- Phát triển plugin cho WordPress: Từ cơ bản đến chuyên nghiệp – Xây dựng plugin tùy chỉnh đầu tiên của bạn
- Từ không đến có: Hướng dẫn toàn diện phát triển plugin WordPress đầu tiên của bạn một cách tuần tự