The basic structure and files of WordPress plugins
A standard WordPress plugin requires at least one main file. This main file is usually named after the plugin itself, for example… my-first-plugin.phpAt the beginning of this file, a specific header comment must be included to declare the plugin’s metadata to the WordPress system. This metadata includes the plugin name, description, version, author, and other information, which will be displayed on the “Plugins” management page in the backend.
In addition to the main file, a fully functional plugin usually includes other directories and files to organize the code. Common directory structures include those used for storing CSS and JavaScript files./assetsTable of contents, including PHP class files/includesTable of contents, as well as those used for user interface templates/templatesTable of Contents. This modular structure facilitates code maintenance and teamwork.
The main file of a plugin serves as the entry point for all its functionality. In addition to declaring metadata, its primary responsibilities include registering and activating/deactivating hooks, loading necessary dependency files, and initializing the core features of the plugin. With proper file organization, even plugins with complex functionalities can maintain a clear and structured layout.
Recommended Reading An Introduction to WordPress Plugin Development。
Create your first basic plugin.
Let’s start by creating the simplest “Hello World” plugin to get familiar with the plugin creation process and its basic lifecycle.
Define plugin information and the main function.
First of all, in the WordPress installation directory on your local machine…/wp-content/plugins/In the path, create a new folder named “hello-world”. Within this folder, create a file named…hello-world.phpThe file.
At the beginning of this file, you need to add plugin header information. A typical plugin header is shown as follows:
<?php
/**
* Plugin Name: 你好世界示例插件
* Plugin URI: https://yourwebsite.com/hello-world
* Description: 这是一个用于演示的简单WordPress插件。
* Version: 1.0.0
* Author: 你的名字
* Author URI: https://yourwebsite.com
* License: GPL v2 or later
* Text Domain: hello-world
* Domain Path: /languages
*/ Next, we will add a simple feature to this plugin: it will automatically insert a piece of text at the end of the article content. We can achieve this by...the_contentThis can be achieved using filters. Add the following code after the header information in the main file:
function hello_world_add_footer_text( $content ) {
// 仅在单篇文章页面添加
if ( is_single() ) {
$footer_text = '<p><em>This article was generated by the “Hello World” plugin.</em></p>';
$content .= $footer_text;
}
return $content;
}
add_filter( 'the_content', 'hello_world_add_footer_text' ); Handling the activation and deactivation of plugins
Professional plugins should properly handle the logic associated with their activation and deactivation. For example, when a plugin is activated, it may be necessary to create database tables or set default options; when it is deactivated, temporary data may need to be cleared. We use…register_activation_hookandregister_deactivation_hookA function is used to register the corresponding hook.
Recommended Reading From Beginner to Expert: Developing WordPress Plugins: Building Custom Functions and Efficient Extensions。
Add the following code to the main file:
// 插件激活时执行的操作
function hello_world_activate() {
// 例如:添加一个选项到数据库
if ( ! get_option( 'hello_world_installed' ) ) {
add_option( 'hello_world_installed', time() );
}
// 可以在这里刷新固定链接规则,以确保新注册的URL结构生效
flush_rewrite_rules();
}
register_activation_hook( __FILE__, 'hello_world_activate' );
// 插件停用时执行的操作
function hello_world_deactivate() {
// 例如:删除我们创建的临时选项(谨慎操作,用户数据通常不删除)
// delete_option( 'hello_world_installed' );
// 清理重写规则
flush_rewrite_rules();
}
register_deactivation_hook( __FILE__, 'hello_world_deactivate' ); After completing the above steps, you will be able to see and activate the “Hello World Example Plugin” on the “Plugins” page in the WordPress administration panel. Once activated, when you visit any article, you will see the added text at the bottom of the content.
Enhancing functionality using the WordPress core API
WordPress provides an extremely rich API that allows plugin developers to interact with the core system in a secure and standardized manner. Mastering these APIs is key to conducting professional development.
Using action hooks and filters
Action Hooks allow you to “insert” and execute your own code at specific points in time. For example, when an article is published, WordPress will trigger the relevant action hook.save_postActions. You can proceed by…add_action()The function mounts its own function onto this hook.
function hello_world_on_post_publish( $post_id, $post, $update ) {
// 检查是否不是修订版本,并且是发布操作
if ( wp_is_post_revision( $post_id ) || $post->post_status != 'publish' ) {
return;
}
// 发送邮件通知或执行其他逻辑
// wp_mail( '[email protected]', '新文章已发布', '文章标题:' . $post->post_title );
}
add_action( 'save_post', 'hello_world_on_post_publish', 10, 3 ); Filter Hooks allow you to modify the data. As mentioned earlier…the_contentAn example is a typical use case for a filter application. Another common example is modifying the title of an article.
function hello_world_modify_title( $title ) {
return '【推荐】' . $title;
}
// add_filter( 'the_title', 'hello_world_modify_title' ); // 谨慎使用,这会修改所有标题 Create a management menu and options page
Many plugins require a backend interface for configuration. WordPress provides functions that make it easy to add top-level menus or sub-menus to the administration panel.
Recommended Reading Master WordPress Plugin Development: Build Efficient Custom Functional Modules from Scratch。
The following code demonstrates how to create a simple options page and use the WordPress Settings API to securely save a setting.
// 步骤1:向管理后台添加一个菜单项
function hello_world_add_admin_menu() {
add_menu_page(
'你好世界设置', // 页面标题
'你好世界插件', // 菜单标题
'manage_options', // 所需权限
'hello-world-settings', // 菜单slug
'hello_world_settings_page', // 用于渲染页面的回调函数
'dashicons-admin-generic', // 图标(可选)
80 // 菜单位置
);
}
add_action( ‘admin_menu‘, ‘hello_world_add_admin_menu’ );
// 步骤2:定义设置页面的HTML内容
function hello_world_settings_page() {
?>
<div class="”wrap”">
<h1>Hello World Plugin Settings</h1>
<form method="”post”" action="/en/”options.php”/" data-trp-original-action="”options.php”">
<?php
settings_fields( ‘hello_world_settings_group’ ); // 输出设置字段和非ce字段
do_settings_sections( ‘hello-world-settings’ ); // 输出设置部分
submit_button(); // 输出提交按钮
?>
<input type="hidden" name="trp-form-language" value="en"/></form>
</div>
<?php
}
// 步骤3:注册设置、字段和章节
function hello_world_settings_init() {
// 注册一个新的设置项到“hello_world_settings_group”组
register_setting( ‘hello_world_settings_group’, ‘hello_world_custom_message’ );
// 在页面中新增一个章节
add_settings_section(
‘hello_world_settings_section’,
‘自定义消息设置’,
‘hello_world_settings_section_callback’,
‘hello-world-settings‘
);
// 向章节中添加一个字段
add_settings_field(
‘hello_world_message_field’,
‘前台显示的消息’,
‘hello_world_message_field_render’,
‘hello-world-settings’,
‘hello_world_settings_section’
);
}
add_action( ‘admin_init’, ‘hello_world_settings_init’ );
// 章节描述的回调函数
function hello_world_settings_section_callback() {
echo ‘<p>Here, you can configure the message content that will be displayed on the frontend by the plugin.</p>’;
}
// 字段渲染的回调函数
function hello_world_message_field_render() {
$option = get_option( ‘hello_world_custom_message’, ‘这是默认消息’ );
echo ‘<input type="”text”" name="”hello_world_custom_message”" value="”‘" . esc_attr( $option ) ‘“ size ="”40”" />’;
} With the code above, you have created a settings page in the background that meets WordPress standards and allows for the secure storage of data.
Plugin Security, Performance, and Preparation for Release
Before sharing a plugin with others or submitting it to the official repository, it is crucial to ensure that it is secure, efficient, and easy to use.
Follow security best practices.
Security is the top priority in plugin development. The primary principle is: never trust user input. All data coming from users or external sources should be treated with caution.$_GET, $_POST, $_COOKIEBefore being used for database queries, displayed on a page, or executed as a system command, all data must be validated, cleaned, or escaped.
For the content that is output to HTML, useesc_html(), esc_attr()Orwp_kses_post()Escape the following functions.
echo ‘<div class="”“‘" . esc_attr( $user_provided_class ) ‘“>’ . esc_html( $user_provided_content ) . ‘</div>’; For database queries, never concatenate variables directly into SQL statements. It is essential to use appropriate methods to insert variable values into the SQL queries.$wpdb->prepare()The method is used for preprocessing.
global $wpdb;
$user_id = 123;
$query = $wpdb->prepare(
“SELECT * FROM {$wpdb->prefix}my_table WHERE user_id = %d”,
$user_id
);
$results = $wpdb->get_results( $query ); In addition, all callback functions that are accessible to users (whether through front-end AJAX or back-end operations) must use…current_user_can()Orcheck_ajax_referer()Functions such as these are used to perform permission and security checks.
Optimize the performance of the plugin.
Plugins with poor performance can negatively impact the user experience of the entire website. Optimization can be approached from several aspects: use caching effectively to avoid performing complex database queries or remote API calls with each page load. WordPress provides a transient API for such purposes.(Transients API)It allows for the convenient storage of temporary data.
// 尝试从缓存获取数据
$data = get_transient( ‘my_plugin_expensive_data’ );
if ( false === $data ) {
// 缓存中没有,执行昂贵操作
$data = expensive_database_query();
// 将结果缓存12小时
set_transient( ‘my_plugin_expensive_data’, $data, 12 * HOUR_IN_SECONDS );
} Secondly, make sure that CSS and JavaScript files are only loaded on the pages where they are needed. By doing so, you can improve the performance of your website by reducing the amount of data that needs to be transferred to users’ browsers.wp_enqueue_script()andwp_enqueue_style()Functions can precisely control the loading of resources and their dependencies. For background resources, they can be mounted to…admin_enqueue_scriptsHook; for front-end resources, it is mounted to...wp_enqueue_scriptsHooks.
Prepare for internationalization and release.
In order for plugins to be used by users around the world, internationalization (i18n) is an essential step. This means that you need to wrap all user-facing strings with specific functions.
Replace the strings in the plugin from:
echo “Hello World!”; Change to:
echo __( ‘Hello World!’, ‘hello-world’ ); Among them‘hello-world’It was you who defined it in the plugin header.Text DomainThen, you can use tools like Poedit to generate the necessary content..potTemplate files, which translators can use to create translations in different languages..poand.moFiles: Place these translation files inside the plugin header.Domain PathThe specified directory (for example)/languagesJust click on it.
Before releasing it, please be sure to write a detailed…readme.txtThe file must comply with the official WordPress format requirements, including a description of the plugin, installation instructions, and answers to common questions. This is a mandatory requirement for submitting the plugin to the WordPress plugin repository. Additionally, adding detailed PHP Doc comments to the plugin code not only helps others understand your code but also demonstrates your professionalism.
summarize
This article systematically outlines the entire process of developing a professional WordPress plugin from scratch. We started by understanding the basic structure of plugins and then created our first simple plugin that included functionality to activate/deactivate the plugin. Next, we delved into WordPress’s powerful action and filter hook systems, learning how to integrate them deeply with the core of WordPress, and how to create standard management settings pages for the plugin. Finally, we emphasized the importance of security best practices, performance optimization techniques, and internationalization (i18n) considerations for plugins intended for a global audience. By mastering these fundamental concepts and skills, you will be able to build professional-level WordPress plugins that are secure, efficient, and easy to maintain, enabling you to meet the needs of both individual users and a broader range of customers.
FAQ Frequently Asked Questions
What basic knowledge is required to develop WordPress plugins?
To develop WordPress plugins, a solid foundation in PHP programming is essential, as plugin code is primarily written in PHP. It is also necessary to have a basic understanding of HTML, CSS, and JavaScript in order to handle the front-end display and interactions. Most importantly, you must be familiar with the core concepts of WordPress, such as Hooks, Shortcodes, Custom Post Types (CPTs), and database operations.$wpdbThe use of…
How to debug the WordPress plugin that is currently being developed?
An effective debugging method is to enable WordPress’s built-in debugging tools.WP_DEBUGPattern. In your…wp-config.phpIn the document, it will be stated that...define( ‘WP_DEBUG’, false );change intodefine( ‘WP_DEBUG’, true );You can also enable them all at the same time.WP_DEBUG_LOGRecord errors in a log file, or enable this feature.WP_DEBUG_DISPLAYErrors should be displayed on the page (only in the development environment). Additionally, using the browser's developer tools (Console, Network tab) is an essential method for debugging front-end JavaScript and AJAX requests.
How can my plugin be compatible with other plugins?
The key to ensuring good compatibility lies in following WordPress's coding standards and using global variables and function names with caution. Adding a unique prefix to your plugin functions, classes, and constants is the best practice to avoid naming conflicts. For example, you can use…myplugin_Or use developer abbreviations as prefixes. When modifying content that may be related to other plugins (such as article text or titles), make sure your filter callback functions have the appropriate priority.add_filter(The third parameter of…) and pay attention to the format of its return value. Use it wisely.class_exists()Orfunction_exists()To check whether a certain class or function has been defined, you can implement conditional loading or provide an alternative solution.
Is it necessary to master Object-Oriented Programming (OOP) in order to develop plugins?
虽然使用传统的面向过程编程方式也可以开发功能完整的插件,但强烈推荐学习和使用面向对象编程(OOP)。OOP能够更好地组织代码,通过类(Class)来封装功能,提高代码的可复用性和可维护性。对于中大型插件项目,使用OOP结合命名空间(Namespaces)和自动加载(Autoloading)是行业内的标准做法,它能让你更清晰地区分不同模块,并显著降低代码的耦合度。
What's next, what's next?
Extended reading and practical knowledge
The following are related to the topic of this article and are suitable for further in-depth reading. Prioritize starting with the article that is closest to your current problem, and gradually expanding to surrounding topics usually works better.
- How to choose and customize the perfect WordPress theme for you
- WordPress Plugin Development Guide: Creating Your First Custom Plugin from Scratch
- Becoming a WordPress Plugin Developer: A Complete Guide from Scratch
- From Zero to One: A Comprehensive Guide and Practical Tips for Building Professional Websites with WordPress
- From Scratch: The Complete Process and Best Practices for Developing Modern WordPress Themes