Starting from scratch: A complete guide to WordPress plugin development and practical tutorials

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

Preparatory work and environment setup

Before developing a WordPress plugin, it is essential to set up a stable local development environment. This will enable you to test and debug your code without affecting the live website.

Selection and Configuration of the Local Development Environment

The most critical step is to set up a local server that integrates PHP, MySQL, and Apache/Nginx. You can choose…MAMPXAMPPSuch integration software packages provide easy installation methods for both Windows and macOS. For more advanced users, they offer additional options and features for customization.DockerContainerizing your development environment is the current best practice, as it ensures consistency and makes it easy to replicate the setup across different systems. Regardless of the method you choose, make sure that your PHP version is compatible with the latest versions supported by your plugins (for example, PHP 7.4 or later), and enable the necessary PHP extensions, such as MySQLi or PDO.

Install and configure WordPress

Once your local server environment is set up, you need to install the WordPress core. Download the latest stable version from the official WordPress.org website and extract it to the root directory of your server’s web hosting space (for example, /www/).htdocsOrwwwThe plugin should be downloaded from the official repository and extracted into a folder within your WordPress installation. Next, access that folder using a web browser and follow the well-known “five-minute installation” guide to complete the setup process. It is recommended to create a dedicated database for plugin development, and make sure to note down the database name, username, and password. After installation, go to the WordPress administration panel and change the default fixed-link structure to a format such as “article name” – this will help test the compatibility of the plugin with WordPress’s permanent links.

Recommended Reading Introduction to WordPress Theme Development: Building Your First Customized Theme from Scratch

Recommended Essential Development Tools

Efficient development is inseparable from having the right tools at hand. First and foremost, you need a code editor—something that is both free and powerful in its features.Visual Studio CodeInstall plugins that are compatible with PHP, WordPress, and provide code intelligence features. Also, obtain a version control tool.GitIt is an essential tool for managing code changes and tracking the history of modifications. Browser developer tools (such as Chrome DevTools or Firefox Developer Edition) are crucial for front-end debugging. Finally, consider installing a code quality inspection tool as well.PHP_CodeSniffercombinationWordPress-Coding-StandardsThe rule set helps you adhere to the official WordPress coding standards.

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

Plugin Basic Structure and Core Files

A standard WordPress plugin has a specific directory and file structure. Following these guidelines is essential for the plugin to be recognized by the system and to be managed effectively.

The basic composition of the main file and its functions

Every plugin must have a main PHP file that serves as the entry point for the plugin. The header comments in this file contain the plugin’s metadata, which is crucial for WordPress to recognize the plugin. Here is the most basic main file for a plugin:my-first-plugin.phpExample:

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

// 防止直接文件访问
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

Plugin NameThis is the only required field, which is used to display the list of background plugins. It is recommended to define it.ABSPATHCheck to prevent malicious users from directly accessing the core files of the plugin.

Add the functional core code to the plugin.

After the header comments, you can start writing the functional code for the plugin. The simplest example is to add a “Hello World” message to the administration panel. You can use…add_actionThe hook allows you to attach a custom function to a specific execution point within WordPress.

Recommended Reading Starting from scratch: A complete guide and practical tutorial for WordPress plugin development

/**
 * 在管理后台顶部显示欢迎信息
 */
function myfp_display_admin_notice() {
    echo '<div class="notice notice-success is-dismissible"><p>Welcome to use “My First Plugin”!</p></div>';
}
add_action( 'admin_notices', 'myfp_display_admin_notice' );

To maintain code organization and avoid naming conflicts, all function and class names should use a unique prefix. For example, in this case…myfp_(My First Plugin)

Plugin Directory and Resource File Organization Standards

A plugin with slightly more complex functionality usually consists of multiple files. A well-structured directory organization can greatly improve maintainability. Common ways to organize the files are as follows:
- /assets/This directory is used to store static resources such as CSS files, JavaScript code, images, and fonts.
- /includes/This directory contains the core PHP class files as well as the function files that implement various functionalities.
- /admin/These files contain PHP, CSS, and JS code that is only related to the administrator backend.
- /public/This folder is used to store files related to the website's front-end.
- /languages/This folder is used to store internationalization translation files (.po and .mo).

Always keep in mind that the main plugin file is located in the root directory of the plugin. When referencing resource files in your code, you should use the correct path to access them.plugin_dir_url( FILE )Orplugin_dir_path( FILE )To dynamically obtain the correct URL or server path.

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%

Hook mechanism interaction with core APIs

The essence of WordPress plugin development lies in its “Hooks” mechanism, which allows your code to be inserted and executed at specific points within the WordPress core, themes, or other plugins.

Understanding Action Hooks and Filter Hooks

Hooks are divided into two main categories: Actions and Filters. Action hooks are used to execute your code when a specific event occurs, such as after an article is published or before a page is loaded. They do not return any value; they simply “perform” an action. The core function used for this is…add_action()anddo_action()Filter hooks are used to modify data. Before the data is used, saved, or displayed, you can intercept and alter it. The hook must return a value. The core function used for this purpose is…add_filter()andapply_filters()

Mounting custom functions to standard hooks

WordPress’s core provides hundreds of standard hooks. For example, you can automatically add a copyright statement at the end of an article’s content, which involves the use of both actions and filters.

Recommended Reading From Beginner to Expert in WordPress Plugin Development: A Step-by-Step Guide to Creating Custom Features

// 使用过滤器修改文章内容
function myfp_add_copyright_to_content( $content ) {
    if ( is_single() ) {
        $copyright_text = '<p><em>Please cite the source when re-posting.</em></p>';
        $content .= $copyright_text;
    }
    return $content;
}
add_filter( 'the_content', 'myfp_add_copyright_to_content' );

// 使用动作在文章保存时执行操作
function myfp_log_post_publish( $post_id ) {
    // 记录日志或执行其他后处理
    error_log( "文章 ID {$post_id} 已发布。" );
}
add_action( 'publish_post', 'myfp_log_post_publish' );

Create and provide custom hooks for extension purposes.

A well-designed plugin should also allow other developers to extend its functionality. You can achieve this by creating your own custom hooks. This not only demonstrates the openness of the plugin architecture but also aligns with WordPress’s own philosophy.

// 定义一个自定义动作钩子
function myfp_process_data() {
    $data = '一些初始数据';
    // 其他开发者可以通过 ‘myfp_before_action’ 在此处插入代码
    do_action( 'myfp_before_action', $data );

// 插件的主要处理逻辑...

// 其他开发者可以通过 ‘myfp_after_action’ 在此处插入代码
    do_action( 'myfp_after_action', $data );
}

// 定义一个自定义过滤器钩子
function myfp_get_output() {
    $output = '默认输出';
    // 允许其他开发者过滤最终的输出
    return apply_filters( 'myfp_filter_output', $output );
}

Create a plugin management interface and settings options.

Most plugins require a backend interface for users to configure them. WordPress offers a variety of APIs to help you create standard setup pages and options quickly and securely.

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.

Using the Settings API for managing security options

The WordPress Settings API is a secure framework for handling form data, validation, storage, and the display of selected options. It automatically manages the nonce security field and performs permission checks. The basic steps for creating a settings page are: 1) Registering the settings, 2) Adding settings blocks, 3) Adding fields. The following code demonstrates how to register a simple setting:

function myfp_register_settings() {
    register_setting(
        'myfp_settings_group', // 选项组名
        'myfp_option_name',    // 选项名(存储在wp_options表中)
        array( 'sanitize_callback' => 'myfp_sanitize_callback' ) // 消毒回调函数
    );

add_settings_section(
        'myfp_settings_section', // 区块ID
        '基本设置',               // 区块标题
        'myfp_section_callback', // 区块回调函数(可输出描述)
        'myfp-settings-page'     // 设置页面Slug
    );

add_settings_field(
        'myfp_text_field',      // 字段ID
        '示例文本输入',         // 字段标签
        'myfp_text_field_callback', // 字段回调函数(输出HTML表单域)
        'myfp-settings-page',   // 页面Slug
        'myfp_settings_section' // 所属区块ID
    );
}
add_action( 'admin_init', 'myfp_register_settings' );

Creating menu and sub-menu pages for different locations

You need to add the link to the settings page to the WordPress administration menu. Use…add_menu_page()It is possible to create a top-level menu and use it.add_submenu_page()Submenus can be created.

function myfp_add_admin_menu() {
    // 添加顶级菜单
    add_menu_page(
        '我的插件设置',        // 页面标题
        '我的插件',            // 菜单标题
        'manage_options',     // 权限能力
        'myfp-settings-page', // 菜单Slug
        'myfp_render_settings_page', // 渲染页面的回调函数
        'dashicons-admin-generic', // 图标(可选)
        80                    // 菜单位置
    );

// 添加子菜单(指向同一个页面,但菜单标题不同)
    add_submenu_page(
        'myfp-settings-page', // 父菜单Slug
        '关于此插件',         // 页面标题
        '关于',              // 菜单标题
        'manage_options',    // 权限能力
        'myfp-about-page',   // 菜单Slug
        'myfp_render_about_page' // 渲染回调
    );
}
add_action( 'admin_menu', 'myfp_add_admin_menu' );

The callback function for rendering the custom settings page

myfp_render_settings_pageThe callback function is responsible for generating the HTML structure of the settings page. Within this function, you need to make calls to…settings_fields()anddo_settings_sections()Output the fields registered by the Settings API.

function myfp_render_settings_page() {
    // 检查用户权限
    if ( ! current_user_can( 'manage_options' ) ) {
        return;
    }
    ?&gt;
    <div class="wrap">
        <h1></h1>
        <form action="/en/options.php/" method="post" data-trp-original-action="options.php">
            <?php
            settings_fields( 'myfp_settings_group' );
            do_settings_sections( 'myfp-settings-page' );
            submit_button( '保存设置' );
            ?>
        <input type="hidden" name="trp-form-language" value="en"/></form>
    </div>
    &lt;?php
}

summarize

WordPress plugin development is a process of transforming creative ideas into functional solutions. The success of a plugin depends on a clear understanding of the underlying infrastructure, a proficient use of the hook system, and a constant focus on security and user experience. From setting up the development environment and writing the main files, to integrating with WordPress using actions and filters, and finally creating a professional administration interface through API settings, every step follows established guidelines and best practices. The key is to maintain the modularity, readability, and scalability of the code; use unique prefixes to avoid conflicts; and always prioritize security. By studying and practicing with this guide, you have acquired the skills needed to build a fully functional, standard-compliant WordPress plugin from scratch.

FAQ Frequently Asked Questions

What programming skills are required to develop a WordPress plugin for ###?
Developing WordPress plugins requires a basic knowledge of the PHP programming language, including its syntax, functions, arrays, and concepts of object-oriented programming. It is also helpful to have a basic understanding of front-end technologies such as HTML, CSS, and JavaScript, as these are essential for creating plugins with user interfaces. Familiarity with the basic operations of the MySQL database is beneficial, as WordPress relies heavily on databases for its functionality.

How to debug the WordPress plugin that is currently being developed?

There are various ways to debug plugins. First of all,wp-config.phpThe file is open in the programWP_DEBUGandWP_DEBUG_LOGThis will log PHP errors and warnings to…/wp-content/debug.logThe file contents are not displayed to the end-users. Secondly, use browser developer tools (such as Chrome DevTools) to debug JavaScript and network requests. For more complex logic, additional methods can be employed.var_dump()Orerror_log()The function outputs the variable values to the log or the page. Additionally, installing professional PHP debuggers such as Xdebug and integrating them with your code editor allows for breakpoint debugging, which is the most efficient method of debugging.

How can my plugin achieve multi-language internationalization?

Implementing internationalization (i18n) mainly uses the tools provided by WordPress.__()_e()_x()Use translation functions such as `translate()` or `gettext()`. In the plugin code, wrap all strings that need to be translated with these functions and specify the text domain (which is defined in the plugin header comments).Text DomainThe value. Then, use a tool like Poedit to scan the plugin’s source code and generate the necessary files..potTemplate files: Translators use these files to create versions of the content in different languages..poAnd the compiled version.moFiles. Finally, place these translated files in the plugin./languages/It should be located in the directory, and used when the plugin is initialized.load_plugin_textdomain()The functions load them.

How can I release my plugin for free in the official WordPress plugin directory?

To publish a plugin to the official WordPress directory, you need to meet a series of requirements. First, make sure your plugin complies fully with the GPL v2 or later license. Second, ensure the quality and security of your code by following WordPress’s coding standards. Next, you need to create an account on WordPress.org and submit your plugin through the “Developers” section. Before submitting, make sure your plugin includes detailed and well-formatted documentation.readme.txtThe file is in a specific Markdown format and has been properly set up for internationalization. After submission, the plugin review team will conduct a review, which may take anywhere from a few days to a few weeks. Once the review is approved, your plugin will be available for searching and installation in the official repository.