Beginner's Guide to Practical Development: A Step-by-Step Tutorial on How to Create WordPress Plugins from Scratch

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

WordPress Plugin Development Environment and Basic Preparation

Before you start writing code, you need a suitable local development environment. This typically includes a local server (such as XAMPP, MAMP, or Local by Flywheel), a code editor (such as VS Code or PHPStorm), and a WordPress installation for testing purposes. Make sure that your PHP version is compatible with the officially recommended version of WordPress.

The core of a WordPress plugin is a component that is located…/wp-content/plugins/The folder located in the directory. The name of this folder should be your plugin identifier; it is recommended to use lowercase letters, numbers, and hyphens. Within this folder, there must be a PHP main file with the same name as the folder itself. For example:my-first-plugin.phpThis file is the entry point for the plugin and contains the plugin’s metadata.

Create your first plug-in file

Let’s start by creating the simplest plugin possible – one that will display a welcome message in the website’s administration panel.

Recommended Reading An in-depth analysis of the WooCommerce plugin: a complete guide from initial setup to advanced customization

The writing of annotations for the plugin header

Every WordPress plugin must start with a specific header comment. WordPress uses this information to identify and display the plugins. In your plugin folder (for example…my-first-pluginIn that, create the main file.my-first-plugin.phpAnd enter the following code:

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%.
<?php
/**
 * Plugin Name: 我的第一个WordPress插件
 * 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
 */

After saving the file, log in to your WordPress administration panel and go to the “Plugins” page. You should see “My First WordPress Plugin” listed in the plugin directory. You can activate it at this point, although it doesn’t have any functionality yet.

Add the first feature to the plugin.

Now, let’s add a simple feature to this plugin: a custom management notification that will be displayed at the top of the admin dashboard. We will use WordPress’s built-in functionality for this.admin_noticesHooks.

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

\n// Add a welcome prompt in the management backend
function my_first_plugin_admin_notice() {
    ?&gt;
    <div class="notice notice-success is-dismissible">
        <p>Welcome to using “My First WordPress Plugin”! You have successfully activated this plugin.</p>
    </div>
    'You have successfully installed the 'My First Plugin'!';

function my_first_plugin_admin_notice() {
    echo 'This is my first plugin!';
}

add_action( 'admin_notices', 'my_first_plugin_admin_notice' );

This code defines a function named "sum", which takes two arguments and returns the sum of those two numbers.my_first_plugin_admin_noticeA function that outputs an HTML snippet to create a closable success message box.add_action()The function “mounts” this custom function to WordPress.admin_noticesThis action is hooked onto a specific hook. Save the file and refresh the WordPress backend, and you will see the green welcome message at the top of the page.

Recommended Reading Practical Tutorial on Website Construction: A Complete Development Process from Scratch to Launch and a Guide to Technology Selection

Understanding the core mechanisms of WordPress plugins: Hooks and Filters

The core of WordPress plugin development lies in the interaction with the WordPress core, which is primarily achieved through a mechanism known as “hooks.” There are two types of hooks: actions and filters.

Using Action Hooks

Action hooks allow you to insert custom code at specific points in the WordPress execution process, just like we used them earlier.admin_noticesAnother common example is…initThe “hook” is triggered during the WordPress initialization process and is commonly used to register custom post types or taxonomies.

For example, we can set an option value when the plugin is initialized:

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 my_first_plugin_set_default_option() {
    // 如果选项不存在,则添加它
    if ( false === get_option( 'my_first_plugin_greeting' ) ) {
        add_option( 'my_first_plugin_greeting', 'Hello from my plugin!' );
    }
}
add_action( 'init', 'my_first_plugin_set_default_option' );

Using Filter Hooks

Filter hooks allow you to modify the data that is passed through the process. For example,the_contentThe filter allows you to modify the output of the article’s main text. We can use it to automatically add a copyright notice at the end of each article.

function my_first_plugin_add_copyright( $content ) {
    // Only applies to single articles in the main loop
    if ( is_single() &amp;&amp; in_the_loop() &amp;&amp; is_main_query() ) {
        $copyright = '  function my_first_plugin_add_copyright( $content ) {
    // Only applies to single articles in the main loop
    if ( is_single() &amp;&amp; in_the_loop() &amp;&amp; is_main_query() ) {
        $copyright = '<p><em>This article is protected by copyright. Please indicate the source when reproducing it.</em></p>'function my_first_plugin_add_copyright( $content ) {
    if ( is_single() ) {
        $content = $content . '<p class='my-copyright'>Copyright © 2021 All rights reserved.</p>';
    } else {
        $content = $content . '<p class="my-copyright">Copyright © 2021 All rights reserved.</p>';
    }
    return $content;
}
add_filter( 'the_content', 'my_first_plugin_add_copyright' );

In this example, the functionmy_first_plugin_add_copyrightReceive the original$contentAfter performing conditional checks (to ensure that this only takes effect on the single article page), a piece of HTML was added to the end of the content. Finally, the modified content must be saved or published.$contentReturn.

Building more complex plugins: Shortcodes and settings pages

A fully functional plugin usually needs to provide both front-end interaction (such as shortcodes) and back-end configuration (such as setting up pages).

Recommended Reading A powerful tool for search engine optimization: Building an SEO strategy for a WordPress website from scratch

Create a custom shortcode

Shortcodes allow users to use simple tags to…[my_greeting]) Insert plugin functionality into an article or page. Register a short code to use it.add_shortcode()Function.

\n// Register a simple greeting shortcode
function my_first_plugin_greeting_shortcode( $atts ) {
    // Use shortcode_atts to define default attributes and merge user input
    $attributes = shortcode_atts( array(
        'name' =&gt; 'Visitor',
    ), $atts );

// Retrieve the option we set earlier
    $greeting_text = get_option( 'my_first_plugin_greeting', 'Hello' );

// Generate the output
    $output = '  \n// Register a simple greeting shortcode
function my_first_plugin_greeting_shortcode( $atts ) {
    // Use shortcode_atts to define default attributes and merge user input
    $attributes = shortcode_atts( array(
        'name' =&gt; 'Visitor',
    ), $atts );

// Retrieve the option we set earlier
    $greeting_text = get_option( 'my_first_plugin_greeting', 'Hello' );

// Generate the output
    $output = '<div class="my-plugin-greeting">';
    $output .= esc_html( $greeting_text ) . ', ' . esc_html( $attributes['name'] ) . '!';
    $output .= '</div>'注:此处的代码示例是用于将中文文本翻译成英文的函数,具体实现请参考官方文档或相关教程。  

function my_first_plugin_greeting_shortcode( $atts, $content ) {  
    $output = 'Hello, world!';  
    return $output;  
}

add_shortcode( 'my_greeting', 'my_first_plugin_greeting_shortcode' );

Now, users can enter text in the editor.[my_greeting name="张三"]The front-end will then display “Hello from my plugin! Zhang San!”

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.

Add a plugin settings page

In order to allow users to customize their greeting messages, we need to add a settings page in the administration backend. This involves creating a top-level menu page or a sub-menu page, as well as handling the saving of form options.

\n// Add a sub-menu page under the “Settings” menu in the background
function my_first_plugin_add_settings_page() {
    add_options_page(
        'My Plugin Settings',   // Page title
        'My First Plugin',   // Menu title
        'manage_options',   // Required permissions
        'my-first-plugin',   // Menu slug
        'my_first_plugin_render_settings_page'   // Callback function for outputting page content
    );
}
add_action( 'admin_menu', 'my_first_plugin_add_settings_page' );

// Render the HTML of the settings page
function my_first_plugin_render_settings_page() {
    ?&gt;
    <div class="wrap">
        <h1>My first plugin settings</h1>
        <form method="post" action="/en/options.php/" data-trp-original-action="options.php">
            <p><strong>Output:</strong>  
  
</p>
        <input type="hidden" name="trp-form-language" value="en"/></form>
    </div>
    &lt;?php
}

// Register settings, sections, and fields
function my_first_plugin_register_settings() {
    register_setting(
        &#039;my_first_plugin_settings_group&#039;, // Setting group name
        &#039;my_first_plugin_greeting&#039;        // Option name
    );

add_settings_section(
        &#039;my_first_plugin_main_section&#039;,    // Section ID
        &#039;Greeting Settings&#039;,                     // Section title
        null,                            // Section callback function (can be empty)
        &#039;my-first-plugin&#039;                // Page slug
    );

add_settings_field(
        &#039;greeting_text_field&#039;,            // Field ID
        &#039;Greeting Text&#039;,                     // Field title
        &#039;my_first_plugin_greeting_field_callback&#039;, // Field HTML callback function
        &#039;my-first-plugin&#039;,                // Page slug
        &#039;my_first_plugin_main_section&#039;    // Section ID
    );
}
add_action( &#039;admin_init&#039;, &#039;my_first_plugin_register_settings&#039; );

// Render the greeting input field
function my_first_plugin_greeting_field_callback() {
    $greeting = get_option( &#039;my_first_plugin_greeting&#039; );
    echo &#039;  &lt;?php
}

// Register settings, sections, and fields
function my_first_plugin_register_settings() {
    register_setting(
        &#039;my_first_plugin_settings_group&#039;, // Setting group name
        &#039;my_first_plugin_greeting&#039;        // Option name
    );

add_settings_section(
        &#039;my_first_plugin_main_section&#039;,    // Section ID
        &#039;Greeting Settings&#039;,                     // Section title
        null,                            // Section callback function (can be empty)
        &#039;my-first-plugin&#039;                // Page slug
    );

add_settings_field(
        &#039;greeting_text_field&#039;,            // Field ID
        &#039;Greeting Text&#039;,                     // Field title
        &#039;my_first_plugin_greeting_field_callback&#039;, // Field HTML callback function
        &#039;my-first-plugin&#039;,                // Page slug
        &#039;my_first_plugin_main_section&#039;    // Section ID
    );
}
add_action( &#039;admin_init&#039;, &#039;my_first_plugin_register_settings&#039; );

// Render the greeting input field
function my_first_plugin_greeting_field_callback() {
    $greeting = get_option( &#039;my_first_plugin_greeting&#039; );
    echo &#039;<input type="text" name="my_first_plugin_greeting" value="' . esc_attr( $greeting ) . '" class="regular-text" />';
}

This code creates a standard WordPress settings page. When a user modifies the greeting on the settings page and saves the changes, the previously created shortcodes will use the new greeting text.

summarize

Through this tutorial, we started from scratch and created a WordPress plugin with basic functionality. You learned how to structure a plugin file, write the plugin header information, use action hooks to send notifications to the backend, use filters to modify content, create shortcodes that users can call on the frontend, and build a complete settings page to manage the plugin’s options. These are the most essential and fundamental skills in WordPress plugin development. Once you have mastered these skills, you can refer to the official WordPress plugin documentation to learn more about APIs such as custom database tables, REST API endpoints, and AJAX handling, and thus develop more powerful and professional plugins.

FAQ Frequently Asked Questions

What programming language skills are required to develop WordPress plugins?

Developing WordPress plugins primarily requires knowledge of the PHP language, as the WordPress core itself is written in PHP. You also need to be familiar with HTML, CSS, and basic JavaScript for building the plugin’s user interface and interactive logic. A basic understanding of SQL is helpful for handling more complex data operations.

How to debug my WordPress plugin?

First of all, make sure that in your…wp-config.phpThe file is open in the programWP_DEBUGThis mode will display PHP errors and warnings on the screen. Secondly, it is also possible to use…error_log()The function writes debug information to the server’s error log. For more advanced debugging, you can consider using specialized PHP debugging tools such as Xdebug, or installing WordPress debugging plugins to help identify and resolve issues.

How can I publish the plugin I developed to the official WordPress plugin directory?

You need to visit WordPress.org and create a developer account. Next, use the Subversion (SVN) tool to submit your plugin code to the code repository assigned to you by the official WordPress team. Your plugin must comply with the GPL license, and the quality, security, and documentation of the code must meet certain review criteria. Once the review is successful, your plugin will be listed in the official repository for users to download.

How should the front-end CSS and JavaScript files of a plugin be loaded correctly?

To avoid conflicts and ensure performance, resources should not be directly included in template files. The correct approach is to use…wp_enqueue_style()andwp_enqueue_script()For the resources in the administration backend, they should be mounted to...admin_enqueue_scriptsHook; for the resources on the website’s front end, they should be mounted to the appropriate location.wp_enqueue_scriptsHooks. This ensures that the dependencies are correctly established and that the same file is not loaded multiple times.