The Ultimate WordPress Plugin Development Tutorial: Build Your First Plugin from Scratch

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

WordPress Plugin Development Basics and Environment Setup

Before you start writing code, it is crucial to understand the basic concepts of WordPress plugins and set up your development environment properly. A WordPress plugin is essentially a collection of one or more PHP files that extends or modifies core functionality through the Hooks system provided by WordPress. A plugin can be as simple as adding a shortcode, or as complex as building a complete e-commerce system.

The core of the development environment is setting up a local server environment. You can use tools such as XAMPP, MAMP, Local by Flywheel, or Docker to quickly build a local WordPress site that includes PHP, MySQL, and Apache/Nginx. Make sure your PHP version is consistent with the currently recommended official WordPress version. For code editors, Visual Studio Code, PhpStorm, and Sublime Text are all excellent choices. They provide syntax highlighting, code completion, and debugging support, significantly improving development efficiency.

A standard WordPress plugin must contain at least one main PHP file, and the header of that file needs to include specific plugin information comments. These comments are key to WordPress recognizing the plugin. In addition, while it is not mandatory, creating a separate directory for your plugin is an excellent practice, as it helps manage asset files, language packs, and other dependencies.

Recommended Reading From Beginner to Expert: A Comprehensive Guide to WordPress Plugin Development for Creating Personalized Websites

Create your first plug-in file

Now, let's start creating the core file for the first plugin. First, you need to go to the WordPress installation directory./wp-content/plugins/folder. Here, create a new folder for your plugin, for example, name itmy-first-plugin

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%.

In that folder, create a main PHP file. Usually, this main file will have the same name as the plugin folder, for examplemy-first-plugin.phpThe beginning of this file must contain the standard 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
 * Domain Path:       /languages
 */

This comment provides all the metadata required for the WordPress plugin admin interface. After saving the file, you will be able to see and activate this plugin on the “Plugins” page in the WordPress admin dashboard. It does not have any functionality yet, but the structure has already been established.

Add a simple feature to the plugin.

After activating the plugin, we will add its first practical feature: displaying a line of custom text in the website footer. We will use WordPress'swp_footerHooks.

In the plugin main filemy-first-plugin.phpBelow the header comment, add the following code:

Recommended Reading Learn WordPress plugin development from scratch: Build custom features and extensions

// 在网站页脚输出自定义文本
function mfp_add_footer_text() {
    echo '<p style="text-align: center; color: #666;">Thank you for using this website! Powered by “My First Plugin”.</p>';
}
add_action( 'wp_footer', 'mfp_add_footer_text' );

Here,mfp_add_footer_textIt is our custom function, which contains the HTML content to be output.add_action()It is the core function used to add action hooks, attaching our function to the WordPress corewp_footerAt this execution point. Save the file and refresh the website frontend, and you will be able to see this line of text at the bottom of the page.

Extend content editing with shortcodes

Shortcodes are a powerful feature provided by WordPress that allow users to insert dynamic content into posts or pages using simple tags. Next, we will create a simple shortcode to display the current date.

In the same main file, continue adding the following code:

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%
// 创建一个显示当前日期的短代码
function mfp_show_current_date( $atts ) {
    // 定义短码的默认属性
    $attributes = shortcode_atts(
        array(
            'format' => 'Y年m月d日',
        ),
        $atts
    );

// 根据属性中的格式返回日期
    return date( $attributes['format'] );
}
add_shortcode( 'show_date', 'mfp_show_current_date' );

functionmfp_show_current_dateDefined the logic for short codes.shortcode_atts()The function is used to merge user-defined properties with default properties, ensuring the robustness of the code. Finally,add_shortcode()Function will[show_date]Associate this tag with our custom handler function.

You can now type in any post, page, or text widget editor[show_date]to display the date in the default format, or use[show_date format="F j, Y"]to display the date in English format.

Understanding Hooks and Filters

The core philosophy of WordPress plugin development is “Hooks.” Hooks are divided into two types: Actions and Filters. What we used beforeadd_action()Just add an action hook.

Recommended Reading Starting from scratch: Building your first WordPress plugin

Action hooks execute your code at specific points in time. They do not expect a return value and are usually used to output content or perform a task, such as adding text to the footer. Filter hooks, on the other hand, are used to modify data. They receive a value, and after it is processed by your function, a modified value must be returned.

Modify article title using filter

Let's create a filter to automatically add a prefix to all article titles. Add the following to the plugin's main file:

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.
// 使用过滤器为文章标题添加前缀
function mfp_add_title_prefix( $title, $id = null ) {
    // 确保只在主循环且是文章页面的标题上生效
    if ( in_the_loop() && is_single() && get_post_type( $id ) === 'post' ) {
        $title = '【推荐阅读】' . $title;
    }
    return $title;
}
add_filter( 'the_title', 'mfp_add_title_prefix', 10, 2 );

Here,the_titleIt is a filter hook.add_filter()The third parameter, “10,” is the priority (the smaller the number, the earlier it runs), and the fourth parameter, “2,” indicates that our handler function accepts two parameters (the original$titleand the post ID). This function checks the conditions and adds a prefix to the title only when on a single post page and within the main loop.

Plugin Security and Best Practices

When developing plugins, security is the top priority. Never trust user input; it must be validated, sanitized, and escaped.

Data Validation and Escaping

When a plugin needs to process data from forms or URLs, it must use the security functions provided by WordPress. For example, usesanitize_text_field()To clean up text input, useesc_html()Oresc_attr()to output HTML or attributes to prevent cross-site scripting (XSS) attacks.

Create a simple settings page

A complete plugin usually needs an admin settings page. Here, we demonstrate how to create a simple options page and securely save a setting.

// 在后台管理菜单中添加一个选项页面
function mfp_add_admin_menu() {
    add_options_page(
        '我的第一个插件设置', // 页面标题
        '我的插件设置',       // 菜单标题
        'manage_options',     // 权限要求
        'my-first-plugin',    // 菜单slug
        'mfp_options_page_html' // 用于显示页面内容的回调函数
    );
}
add_action( 'admin_menu', 'mfp_add_admin_menu' );

// 注册一个设置项
function mfp_settings_init() {
    register_setting( 'mfpPlugin', 'mfp_settings' ); // 设置组,选项名

add_settings_section(
        'mfp_plugin_section', // 区块ID
        '基础设置',           // 区块标题
        null,                 // 区块介绍的回调函数(此处为null)
        'my-first-plugin'     // 所属页面slug
    );

add_settings_field(
        'custom_text',        // 字段ID
        '自定义显示文本',     // 字段标签
        'mfp_custom_text_field_html', // 用于输出字段HTML的回调函数
        'my-first-plugin',    // 页面slug
        'mfp_plugin_section'  // 所属区块ID
    );
}
add_action( 'admin_init', 'mfp_settings_init' );

// 渲染设置字段的HTML
function mfp_custom_text_field_html() {
    $options = get_option( 'mfp_settings' );
    $value = isset( $options['custom_text'] ) ? esc_attr( $options['custom_text'] ) : '';
    ?&gt;
    <input type='text' name='mfp_settings[custom_text]' value='<?php echo $value; ?>'>
    <p class="description">The text entered here will be displayed in the footer.</p>
    <?php
}

// 渲染整个选项页面的HTML
function mfp_options_page_html() {
    // 检查用户权限
    if ( ! current_user_can( 'manage_options' ) ) {
        return;
    }
    ?>
    <div class="wrap">
        <h1></h1>
        <form action="/en/options.php/" method="post" data-trp-original-action="options.php">
            <?php
            settings_fields( 'mfpPlugin' ); // 输出安全字段
            do_settings_sections( 'my-first-plugin' ); // 输出设置区块和字段
            submit_button( '保存设置' );
            ?>
        <input type="hidden" name="trp-form-language" value="en"/></form>
    </div>
    &lt;?php
}

This code creates a subpage under the “Settings” menu for saving a custom piece of text. Note the check on user permissions within it.current_user_can) and escaping output data (esc_html, esc_attr), all of these are part of security practices. After that, you can modify the function previously output in the footer, starting fromget_option( 'mfp_settings' )Read this value from it for dynamic display.

summarize

Through this tutorial, you have completed the entire process of building a fully functional WordPress plugin from scratch. You learned how to create the plugin’s basic file structure and use action hooksadd_actionAdd content to the footer viaadd_shortcodeCreate custom shortcodes and use filter hooksadd_filterModify article data. More importantly, you have been exposed to the core concepts of plugin security and practiced how to create a secure admin settings page to manage plugin options.

Plugin development is a continuous process of learning and practice. Next, you can try adding internationalization support to the plugin (using__()and_e()functions), introduce JavaScript and CSS resources, or use object-oriented programming (OOP) to refactor the code structure, making it easier to maintain and extend. Remember, reading the official WordPress Plugin Handbook and core code is the best way to improve your skills.

FAQ Frequently Asked Questions

How to debug my WordPress plugin?

Enabling WordPress debug mode is the first step. On the website'swp-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 writes information to the server's error log, or you can use a professional debugging plugin such as Query Monitor to view database queries, hook execution, and performance data.

How can my plugin be compatible with different versions of WordPress?

In plugin code, you should use conditional checks to verify the existence of WordPress core functions, classes, or constants before using them. You can usefunction_exists()class_exists()Ordefined()make a judgment. At the same time, in the plugin'sreadme.txtClearly declare in the file the minimum WordPress version your plugin supports (viaRequires at leastfield), which can help users understand compatibility.

Does developing plugins necessarily require the use of object-oriented programming?

Not necessarily. You can use purely procedural programming (just like the examples in this tutorial) to develop fully functional plugins. The main advantages of object-oriented programming (OOP) are better code organization, encapsulation, and reusability, which are more beneficial for large, complex plugin projects. For small plugins, procedural programming may be simpler and more straightforward. You can choose the appropriate approach based on the size and complexity of the project.

How do I publish my plugin to the official WordPress plugin directory?

First, you need to register an account on WordPress.org and submit the plugin. Your plugin code must comply with the official coding standards and guidelines, including security, no malicious code, use of a GPL-compatible license, and so on. You need to create a detailedreadme.txtfiles, and ensure that the main file header comments of the plugin comply with the standards. After submission, a volunteer from the plugin review team will review it, and once approved, it can be published.