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

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

Mastering WordPress plugin development is a core skill for expanding website functionality and meeting personalized needs – it is far more effective than simply modifying the theme itself. functions.php Compared to using custom files, using plugins ensures that the functionality is independent of the theme, which makes it easier to migrate, manage, and maintain. This article will guide you through the process of creating a plugin from scratch, ensuring that it has a well-structured design and complies with WordPress coding standards.

Preparatory work and environment setup

Before you write the first line of code, you need a suitable development environment and a basic understanding of the WordPress architecture.

Development Environment Configuration

A standard local development environment is the foundation for efficient development. Tools such as XAMPP, MAMP, or Local by Flywheel are recommended; they allow you to install Apache, MySQL/Nginx, PHP, and WordPress with just one click. Additionally, make sure that your text editor or Integrated Development Environment (IDE) – such as VS Code or PhpStorm – supports PHP syntax highlighting and code suggestions, as this will greatly enhance your development efficiency.

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

Understanding the WordPress plugin architecture

A WordPress plugin is essentially one or more PHP files that are stored in a specific location within the WordPress directory structure. wp-content/plugins/ It is located within the directory. Its core principle is the “hook” mechanism. Plugins execute code at specific times through “action hooks” or modify the data output by other functions using “filter hooks”. add_action and add_filter These two functions are the key to getting started with plugin development.

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 your first plugin: a greeting gadget

We will create a simple plugin called “Daily Greetings.” It will display a custom welcome widget on the dashboard of the website’s administration panel.

Create the main plugin file

Firstly, in wp-content/plugins/ Create a new folder under the directory and name it my-first-greeting-pluginWithin this folder, create the main plugin file. my-first-greeting-plugin.php

Every plugin must start with a standard plugin header comment, which is the identifier that WordPress uses to recognize plugin information. Open the main file and enter the following code:

<?php
/**
 * Plugin Name: 每日问候
 * Plugin URI:  https://www.yourwebsite.com/my-first-greeting-plugin
 * Description: 这是一个示例插件,用于在仪表盘显示个性化问候。
 * Version:     1.0.0
 * Author:      Your Name
 * Author URI:  https://www.yourwebsite.com
 * License:     GPL v2 or later
 * Text Domain: my-first-greeting
 */

After saving the file, go to the “Plugins” page in the WordPress administration dashboard. You should see the “Daily Greetings” plugin in the list and be able to activate it. At this point, it doesn’t have any functionality yet.

Recommended Reading The Ultimate Guide to WordPress Plugin Development: Building Your First Plugin from Scratch

Add widgets to the dashboard.

Next, we will use WordPress to… wp_dashboard_setup Use action hooks to add a custom dashboard widget. Below the comments at the top of the main file, add the following code:

// 添加仪表盘小工具
function mfgp_add_dashboard_widget() {
    wp_add_dashboard_widget(
        'mfgp_dashboard_widget',          // 小工具唯一ID
        '每日问候',                       // 小工具标题
        'mfgp_dashboard_widget_content'  // 显示内容的回调函数
    );
}
add_action( 'wp_dashboard_setup', 'mfgp_add_dashboard_widget' );

// 定义小工具内容
function mfgp_dashboard_widget_content() {
    $user = wp_get_current_user();
    $hour = date('G'); // 获取当前小时(24小时制)

if ( $hour &gt;= 5 &amp;&amp; $hour \n &lt;= 12 && $hour &lt; 18 ) {
        $greeting = &#039;下午好&#039;;
    } else {
        $greeting = &#039;晚上好&#039;;
    }

echo &#039;<p>' . sprintf( esc_html__( '%s,%s!欢迎回来。', 'my-first-greeting' ), $greeting, esc_html( $user-&gt;display_name ) ) . '</p>'echo '<p>'\n' . esc_html__( 'This is the greeting widget created by your first plugin.', 'my-first-greeting' ) . '</p>';
}

This code does two things: First, it defines a function. mfgp_add_dashboard_widgetUse wp_add_dashboard_widget The function registers a small utility. Then, it is defined. mfgp_dashboard_widget_content The function is used to generate the content for the small tool. It displays different greetings depending on the time of day and also includes the name of the currently logged-in user. Note that we have used… esc_html__() and esc_html() Preparing functions for translation and escaping output are important practices to ensure security and internationalization.

After activating the plugin, refresh the dashboard page, and you will see the “Daily Greeting” widget.

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%

Enhanced plugin functionality and security practices

A basic plugin has been completed, but to make it more robust and professional, we need to focus on security, maintainability, and user configuration.

Add a plugin settings page

It would be more useful if users could customize their greeting messages. We will create a simple settings page for the plugin.

First, use admin_menu The action hook has been updated to include a sub-menu page:

Recommended Reading WordPress Plugin Development Beginner’s Guide: Build Your First Custom Plugin from Scratch

// 添加设置菜单
function mfgp_add_admin_menu() {
    add_options_page(
        '每日问候设置',                // 页面标题
        '每日问候',                    // 菜单标题
        'manage_options',             // 所需权限
        'my-first-greeting-plugin',   // 菜单slug
        'mfgp_settings_page_content' // 回调函数
    );
}
add_action( 'admin_menu', 'mfgp_add_admin_menu' );

Then, create the content for the settings page, the options for registering new settings, and the functionality to handle form submissions.

// 设置页面内容
function mfgp_settings_page_content() {
    ?&gt;
    <div class="wrap">
        <h1></h1>
        <form action="/en/options.php/" method="post" data-trp-original-action="options.php">
            <?php
            settings_fields( 'mfgp_settings_group' ); // 输出安全字段
            do_settings_sections( 'my-first-greeting-plugin' ); // 输出设置区块
            submit_button(); // 输出提交按钮
            ?>
        <input type="hidden" name="trp-form-language" value="en"/></form>
    </div>
    <?php
}

// 初始化设置
function mfgp_settings_init() {
    register_setting(
        'mfgp_settings_group', // 选项组名
        'mfgp_custom_message', // 选项名
        array( 'sanitize_callback' => 'sanitize_text_field' ) // 清理回调
    );

add_settings_section(
        'mfgp_section', // 区块ID
        '自定义问候设置', // 区块标题
        null, // 区块描述回调(无)
        'my-first-greeting-plugin' // 所属页面
    );

add_settings_field(
        'mfgp_field',
        '自定义问候语前缀',
        'mfgp_field_callback', // 输出字段HTML的回调
        'my-first-greeting-plugin',
        'mfgp_section'
    );
}
add_action( 'admin_init', 'mfgp_settings_init' );

// 设置字段的回调函数
function mfgp_field_callback() {
    $value = get_option( 'mfgp_custom_message', '祝您有愉快的一天,' );
    echo '<input type="text" name="mfgp_custom_message" value="' . esc_attr( $value ) . '" class="regular-text" />'echo '<p class="description">This text will be added before the greeting.</p>';
}

Finally, modify the function that updates the content of the small tool to ensure that the user's custom settings take effect.

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.
// Update the content of the widget and use a custom message
function mfgp_dashboard_widget_content() {
    $user = wp_get_current_user();
    $hour = date('G');
    $custom_msg = get_option( 'mfgp_custom_message', 'Have a nice day,' );

if ( $hour &gt;= 5 &amp;&amp; $hour &lt; \n &lt;= 12 && $hour &lt; 18 ) {
        $greeting = &#039;下午好&#039;;
    } else {
        $greeting = &#039;晚上好&#039;;
    }

echo &#039;<p>'.' . esc_html( $custom_msg ) . sprintf( esc_html__( '%s, %s!', 'my-first-greeting' ), $greeting, esc_html( $user-&gt;display_name ) ) . '</p>';
}

Now, under the “Settings” menu in the WordPress administration panel, a “Daily Greetings” option page has been added. Administrators can save a custom greeting prefix.

Comply with security and coding standards.

During the development process, it is essential to follow WordPress security best practices: use the appropriate escape functions for all data that comes from users or the database and is intended to be displayed on the website. esc_html, esc_attr, esc_url); Validate and clean all user input (for example, by using…) sanitize_text_field) ; Use wp_kses_post Or wp_kses This allows for the use of safe HTML. It is also recommended to follow the relevant guidelines and best practices. WordPress Official PHP Coding StandardsTo ensure the clarity and consistency of the code.

Plugin internationalization and release preparation

To make your plugin available to users around the world, internationalization is an essential step. At the same time, preparing it for release in the official directory also requires following certain guidelines and standards.

Implement the internationalization of the plug-in

We have already used it in the code. esc_html__() To package the string that needs to be translated, you need to create a file in the plugin directory. To achieve internationalization, you should follow these steps: languages Create a folder. Then, add the following code after the comments at the beginning of the main file to load the text field:

// 加载文本域以实现国际化
function mfgp_load_textdomain() {
    load_plugin_textdomain( 'my-first-greeting', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
}
add_action( 'plugins_loaded', 'mfgp_load_textdomain' );

After that, you can use tools like Poedit to scan the translation strings in the plugin code and generate the necessary files. .pot Template files, and for different languages (such as Chinese) zh_CNCreate .po And the compiled version .mo File, put it in languages Folder.

Prepare to publish it to the official directory

If you plan to submit the plugin to the WordPress.org plugin directory, you need to ensure the quality of the code and include the necessary metadata files. For example, create a… readme.txt The file must be in a format that complies with the specified requirements. Specific guidelines for WordPressThe documentation should include the plugin name, description, installation instructions, common questions, and update logs. Additionally, consider adding an uninstallation hook to clean up the options in the database when the user deletes the plugin.

// 插件卸载时清理选项
function mfgp_uninstall_hook() {
    delete_option( 'mfgp_custom_message' );
}
register_uninstall_hook( __FILE__, 'mfgp_uninstall_hook' );

summarize

By creating this “Daily Greeting” plugin, we have completed the entire core process of WordPress plugin development: from establishing the basic file structure, adding functionality using action hooks, to creating a management interface, implementing security guidelines, and preparing for internationalization. The key lies in understanding and proficiently utilizing WordPress’s hook system, while always prioritizing security and code standards. This simple example serves as the starting point for your own plugin development journey. From here, you can explore more advanced concepts such as shortcodes, custom post types, REST API endpoints, and more, to create powerful and professional plugins.

FAQ Frequently Asked Questions

In which directory must the plugin be placed?

WordPress plugins must be placed on the website’s server. wp-content/plugins/ Within the directory, each plugin can be an independent PHP file. However, it is more common for a plugin to consist of a folder with the same name as the plugin, which contains the main file and other resources.

Why doesn’t my plugin appear in the background list?

Please check whether the format of the header comments (such as Plugin Name and Description) in the main plugin file is correct and complete. Ensure that the file is located in the correct directory, and that WordPress has the necessary permissions to read it. Additionally, verify that there are no unnecessary spaces or characters at the beginning of the PHP code.

How to debug PHP errors in a plugin?

In wp-config.php In the document, it will be stated that... WP_DEBUG The constant is set to trueThis will allow WordPress to display PHP errors, warnings, and notifications on the page. Please note that this feature should only be enabled in a development environment and must be disabled before going live.

What is the difference between the functions.php files in plugins and themes?

In the topic of… functions.php The features added in the system are bound to a specific theme; when the theme is changed, these features may become unavailable. However, the features provided by plugins are independent of the theme. As long as the plugin is activated, the features will always be available regardless of the theme being used. For features that need to be universally available (i.e., usable across all themes), developing a plugin is the better option.

How can I enable other developers to extend my plugin?

You can allow other developers to extend your plugin by providing custom “action hooks” and “filter hooks”. do_action() Create action hooks to “perform actions” in the places where code injection is required. apply_filters() Create filter hooks that allow them to modify certain data values within your plugin. This is a common pattern for collaboration between plugins within the WordPress ecosystem.