Starting from scratch: Building your first WordPress plugin

3-minute read
2026-03-14
2026-06-04
2,791
I earn commissions when you shop through the links below, at no additional cost to you.

Starting from scratch: Building your first WordPress plugin

WordPress plugin development is a core way to extend the core functionality of WordPress. By creating plugins, developers can add custom features to websites without modifying themes or core files, which ensures the independence and portability of the features. A standard plugin typically consists of a main PHP file, optional resource files (such as CSS and JavaScript), and language packs. Understanding the basic structure of plugins is the first step towards successful development.

The basic structure and creation of WordPress plugins

The most basic form of a plug-in is a file placed in a specific folder on the computer./wp-content/plugins/The folder under the directory. This folder must contain at least one main PHP file, and the header comments of this file are used to declare the plugin information to WordPress.

The writing of annotations for the plugin header

Every plugin's main file must begin with a specific PHP comment block, which is called the plugin header. WordPress identifies and displays your plugin in the plugin list in the admin backend by reading this information. A standard header comment is shown as follows:

Recommended Reading In-depth Analysis of WordPress Plugin Development: From Beginner to Efficient Customization

<?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
 */

Among them,Plugin NameIt is necessary to fill in all the required fields, and the other fields are optional. However, for the integrity and professionalism of the plug-in, it is recommended to fill in all the fields as completely as possible.Text DomainIt is used for internationalization and serves as the foundation for subsequent plugin translations.

UltaHost WordPress Hosting
30-day refund guarantee, unlimited bandwidth and database usage, free DDoS protection; purchase for 3 years and get a discount of 50%.

Create the main file and directory for the plugin

Firstly, in/wp-content/plugins/Create a new folder under the directory, for examplemy-first-pluginThen create the main PHP file inside that folder; it usually has the same name as the folder.my-first-plugin.phpWrite the above header comments into the file, save it, and you'll be able to see and activate it on the “Plugins” page in the WordPress backend. At this point, it doesn't have any functionality yet.

Core development concepts: action hooks and filters

The plugin architecture of WordPress is built on a “hook” system, which serves as a bridge for plugins to interact with the core. Hooks are mainly divided into two categories: action hooks and filter hooks.

Understanding and using action hooks

Action hooks allow you to execute custom PHP code at specific points in time or when certain events occur. You can use them to...add_action()The function “mounts” your function to a hook. For example, it automatically adds a paragraph of text to the end of the article content:

function myplugin_add_footer_text( $content ) {
    if ( is_single() ) {
        $content .= '<p>Thank you for reading!</p>';
    }
    return $content;
}
add_filter( 'the_content', 'myplugin_add_footer_text' );

Note that this example actually uses filter hooks to modify the content. A typical example of an action hook is adding a menu in the administration backend:

Recommended Reading Learn WordPress plugin development from scratch: Build your first custom feature

function myplugin_add_admin_menu() {
    add_menu_page(
        '我的插件设置',
        '我的插件',
        'manage_options',
        'myplugin-settings',
        'myplugin_settings_page'
    );
}
add_action( 'admin_menu', 'myplugin_add_admin_menu' );

Here,add_action()Convert the functionmyplugin_add_admin_menuBind toadmin_menuThis action hook is called by WordPress when building the backend menu.

Understand and use filter hooks

Filter hooks are used to modify the data generated by WordPress during its processing. You can use them toadd_filter()Use a function to mount your function. The filter function receives the input value, modifies it, and then must return the modified value. For example, modifying the article title:

function myplugin_modify_title( $title ) {
    return '精选: ' . $title;
}
add_filter( 'the_title', 'myplugin_modify_title' );

Filters are very powerful and are often used to modify query results, text content, option values, and almost all other data generated by WordPress.

hosting.com Shared Hosting
High performance with AMD EPYC CPUs, NVMe SSD storage and LiteSpeed, 24/7, 24x7 expert in-house support, advanced security measures including SSL, brute force, malware and DDoS protection, savings of up to 73%

Add a settings page and options for the plugin

A fully functional plugin typically needs to provide users with configuration options. WordPress provides a settings API to create option pages in a secure and standardized manner.

Create management menus and pages

First of all, you need to useadd_menu_page()Oradd_options_page()We can use functions like add_admin_page() to add a management page. We usually mount this operation toadmin_menuOn the hook, as shown in the previous example. Among them,myplugin_settings_pageIt's a callback function used to render the HTML content of the settings page.

Use the Settings API to register options

The Settings API provides a secure way to register, verify, and save settings. The core steps include: usingregister_setting()Register a setup group and use it.add_settings_section()Add a settings block and use it.add_settings_field()Add specific setting fields.

Recommended Reading WordPress Plugin Development Complete Guide: An Practical Tutorial from Beginner to Expert

function myplugin_settings_init() {
    // 注册一个设置
    register_setting( 'myplugin_settings', 'myplugin_options' );

    // 添加一个设置区块
    add_settings_section(
        'myplugin_section_general',
        '通用设置',
        'myplugin_section_general_cb',
        'myplugin-settings'
    );

    // 添加一个设置字段
    add_settings_field(
        'myplugin_field_text',
        '欢迎语',
        'myplugin_field_text_cb',
        'myplugin-settings',
        'myplugin_section_general',
        [ 'label_for' => 'myplugin_field_text' ]
    );
}
add_action( 'admin_init', 'myplugin_settings_init' );

Then, you need to write the corresponding callback functionmyplugin_section_general_cbandmyplugin_field_text_cbOutput the HTML input box for the block description and fields. Finally, inmyplugin_settings_pageIn the function, we usesettings_fields()anddo_settings_sections()Use a function to output the entire form.

Plugin Security and Best Practices

When developing plug-ins, security is the top priority. An unsafe plug-in could jeopardize the entire website.

InterServer Shared Hosting
Shared hosting $2.50 USD per month , first month $0.1 USD promo code tryinterserver, 461 cloud apps scripts, one click install.

Data Validation, Cleaning, and Escaping

Never trust user input or data from the database. When processing any input (such as $_POST, $_GET), it is necessary to verify and clean it. WordPress provides a large number of functions, such assanitize_text_field(), intval(), wp_kses()And so on. When outputting data to HTML or JavaScript, it is necessary to escape it, using functions such asesc_html(), esc_attr(), esc_js()andwp_json_encode()

// 接收、清理并保存数据
$user_input = sanitize_text_field( $_POST['my_field'] );
update_option( 'my_option', $user_input );

// 安全地输出数据
echo esc_html( get_option( 'my_option' ) );

\nUsing non-CE and permission checks

For all background form submissions or AJAX requests initiated by plugins, WordPress’ Nonce (Random Value with Expiration Time) must be used to verify the legitimacy and uniqueness of the requests, in order to prevent cross-site request forgery (CSRF) attacks. At the same time, it is also necessary to…current_user_can()The function checks whether the current user has the necessary permissions to perform this operation.

// 在表单中输出 nonce 字段
wp_nonce_field( 'myplugin_action', 'myplugin_nonce' );

// 在处理请求时验证 nonce 和权限
function myplugin_handle_form_submit() {
    if ( ! isset( $_POST['myplugin_nonce'] ) ||
         ! wp_verify_nonce( $_POST['myplugin_nonce'], 'myplugin_action' ) ||
         ! current_user_can( 'manage_options' ) ) {
        wp_die( '安全校验失败。' );
    }
    // ... 安全地处理数据 ...
}

summarize

WordPress plugin development is a systematic project. It starts with understanding the basic structure and hook mechanism, then implementing functions and creating user interfaces, and finally adhering to strict security practices. By following WordPress' coding standards and making full use of the APIs it provides, developers can build powerful, secure, and easy-to-maintain plugins. The key lies in seamlessly integrating custom functions into WordPress' lifecycle through actions and filter hooks, while using the Settings API to manage configurations and always prioritizing data validation, cleaning, escaping, and permission checks.

FAQ Frequently Asked Questions

How to debug my WordPress plugin?
Enabling the debugging mode of WordPress is the first step. Inwp-config.phpIn the document, it will be stated that...WP_DEBUGThe constant is set totrueThis will directly display PHP errors, warnings, and notifications on the page. For more advanced debugging, you can use…error_log()The function logs the information to the server's error log, or uses a dedicated debugging plug-in to view detailed information about queries, hooks, and so on.

How can my plugin implement multi-language support?

WordPress uses the GNU gettext framework to implement internationalization. Firstly, it defines the relevant information in the plugin header comments.Text DomainIn the plugin code, use < for all strings that need to be translated.__()For translation, please use_e()Carry out the translation and output it directly. Then, use tools such as Poedit to extract strings from the plugin source code and generate them..potFirst, create the template file, and then create corresponding ones for each language..poAnd the compiled version.moThe files should be placed in the plugin's folder./languages/Under the directory.

How to avoid conflicts between class names in plugins and those of other plugins?

To avoid conflicts in class names, function names, or constant names, the best practice is to use namespaces or add a unique prefix to all identifiers. Since PHP 5.3, it is recommended to use namespaces. For example, declarenamespace MyPluginAdmin;If we consider compatibility, we must use a prefix, and the prefix should be unique enough. For example, we can use a combination of the company name and the plugin name's abbreviation:function acme_myplugin_init() {}The class name is defined asclass Acme_MyPlugin_Admin_Settings {}

How to add a custom database table for my plugin?

The best time to create a custom table is when the plugin is activated. You can encapsulate the code for creating the table in a function and execute it viaregister_activation_hook()Register the function. Inside the function, usedbDelta()The function is used to safely create or update table structures, which requires the use of a very specific SQL format. It is essential to use it correctly.$wpdb->prefixAdd a site prefix to the table name to support a multi-site environment.