Getting Started from Scratch: Building Your First WordPress Plugin

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

Preparatory work before development

Before we start writing code, we need to ensure that the development environment is set up correctly and understand the basic structure of WordPress plugins. A suitable local development environment is the foundation for efficient work.

Build a local development environment

First, you need a local server environment to run WordPress. It is recommended to use integrated tools such as XAMPP, MAMP, or Local by Flywheel. After installing WordPress, you can wp-content/plugins Start your plugin development in the directory. This directory is where all plugins are stored, whether they are developed by yourself or installed from the official directory.

Understand the core files of the plug-in

Every WordPress plugin requires at least one main file, which serves as the plugin's “ID card” and “launcher”. The main file is usually named after the plugin's function, for example, "Contact Form" or "Image Gallery". my-first-plugin.phpThe comment block at the top of this main file is crucial. It describes the basic information of this plugin to the WordPress system.

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

Create your first plug-in file

Now, let's start from the most basic part and create a simple plug-in with actual functionality.

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

Write the header comments for the plug-in

In wp-content/plugins Under the directory, create a file named my-first-plugin Create a new folder. Then, create the main file within that folder my-first-plugin.phpAt the very top of this file, you need to add a plugin information header comment that complies with WordPress standards.

<?php
/**
 * Plugin Name:       我的第一个插件
 * Plugin URI:        https://yourwebsite.com/my-first-plugin
 * Description:       这是一个用于学习的简单插件,用于在文章末尾添加自定义文本。
 * Version:           1.0.0
 * Author:            你的名字
 * Author URI:        https://yourwebsite.com
 * License:           GPL v2 or later
 * Text Domain:       my-first-plugin
 */

This code tells WordPress that this is a plugin, and defines the name, description, version, and other information that will be displayed in the backend management interface. After saving the file, you log in to the WordPress backend and go to the “Plugins” page. You should be able to see your plugin appear in the list. Now you can activate it, even though it doesn't have any functionality yet.

Implement a basic function: filter the content of articles

After activating the plugin, we need to make it do something. A common entry-level function is to modify the article content. We will use the Yoast SEO plugin for this purpose. the_content This filter hook automatically adds a customized text at the end of each article.

In the main file my-first-plugin.php Below the header comments, we add the function code:

Recommended Reading How to Create a Professional WordPress Theme: A Complete Guide from Start to Launch

// Add custom text to the end of the post content
function myfp_add_custom_text_to_content( $content ) {
    // Ensure that it is only added to a single post page in the main loop
    if ( is_single() &amp;&amp; in_the_loop() &amp;&amp; is_main_query() ) {
        $custom_text = '<p><strong>Thank you for reading! This article is supported by “My First Plugin”.</strong></p>';
        $content . = $custom_text.
    }
    return $content.
}
// Mount our function to the ‘the_content’ filter
add_filter( 'the_content', 'myfp_add_custom_text_to_content' );

This code defines a function named "sum", which takes two arguments and returns the sum of those two numbers. myfp_add_custom_text_to_content The function. It receives the content of the article. $content As a parameter, it ensures that the text is only added to the single article page of the website's front end through conditional judgment, avoiding it from taking effect on other pages (such as the list page). Then, it appends a custom HTML paragraph to the original content and returns the modified content. Finally, it uses < add_filter() The function “mounts” this custom function to the core of WordPress. the_content On the filter. In this way, every time WordPress is about to output the article content, it will first execute our function.

After saving the file, go to the front page of the website and check any article. You will find that the thank-you text we added has already appeared at the bottom of the page.

Add management options for the plugin

A fully functional plug-in usually requires some configuration options, allowing users to set them in the background. We will add a settings page for the “Custom Text” function we mentioned earlier.

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%

Create a plugin management menu

First, we need to add a new menu item in the administration sidebar of the WordPress backend. This requires the use of WordPress's add_action() Functions and admin_menu Hooks.

// 添加管理菜单
function myfp_add_admin_menu() {
    add_options_page(
        '我的第一个插件设置', // 页面标题
        '我的插件设置',       // 菜单标题
        'manage_options',    // 权限要求
        'my-first-plugin',   // 菜单 slug
        'myfp_options_page_html' // 显示设置页面的回调函数
    );
}
add_action( ‘admin_menu’, ‘myfp_add_admin_menu’ );

add_options_page() The function will create a sub-menu item under the “Settings” main menu. It requires several parameters: the page title, the menu title, the user permissions, a unique menu identifier (slug), and the name of a callback function used to output the HTML content of the settings page. myfp_options_page_html

Create the setup page and save the data

Next, we need to define a callback function to render the settings page and process the data submitted by the user.

Recommended Reading WordPress Plugin Development Tutorial: Building Your First Plugin from Scratch

// 渲染设置页面的HTML
function myfp_options_page_html() {
    // 检查用户权限
    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’ );
            // 输出设置区域
            do_settings_sections( ‘my-first-plugin’ );
            // 输出提交按钮
            submit_button( ‘保存设置’ );
            ?>
        <input type="hidden" name="trp-form-language" value="en"/></form>
    </div>
    ‘myfp_field_custom_text’ ]
    );
}
add_action( ‘admin_init’, ‘myfp_settings_init’ );

// Render the HTML for the text box
function myfp_field_custom_text_html() {
    // Retrieve the saved value from the database
    $options = get_option( ‘myfp_options’ );
    $value = $options[‘myfp_field_custom_text’] ?? ‘’; // Use the null coalescing operator to assign an empty value if it doesn’t exist
    ?&gt;
    <input type="“text”"
           id="“myfp_field_custom_text”"
           name="“myfp_options[myfp_field_custom_text]”"
           value="“NO NUMERIC NOISE KEY" 1000”
 class="“regular-text”">
    &lt;?php
}

This code uses the following methods to achieve the desired effect: register_settingadd_settings_section and add_settings_field A series of functions were used to create a settings page that includes a text input box, in accordance with WordPress's Settings API. The content entered by users will be securely stored. wp_options The data table's myfp_options In the records.

Finally, we need to modify the function that previously filtered the article content, so that it uses the text retrieved from the database instead of the hardcoded text.

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 myfp_add_custom_text_to_content( $content ) {
    if ( is_single() &amp;&amp; in_the_loop() &amp;&amp; is_main_query() ) {
        $options = get_option( ‘myfp_options’ );
        $custom_text = $options[‘myfp_field_custom_text’] ?? ‘’;
        if ( ! empty( $custom_text ) ) {
            $content .= ‘<p><strong>’\n‘ . esc_html( $custom_text ) . '</strong></p>’;
        }
    }
    return $content;
}

Now, users can enter any text in the “Settings” -> “My Plugin Settings” page, and after saving, the text will be displayed at the end of all articles on the website.

Advanced Practices of Plugin Development and Preparation for Release

After the basic functions are completed, we need to consider the robustness and maintainability of the plug-in, as well as how to share it with others for use.

Add security and internationalization support

Security is a top priority in plugin development. In the example above, we have already used esc_html() and esc_attr() We use functions such as these to escape the output and prevent XSS attacks. When processing user input, executing database queries, or importing external files, we must always use the security functions provided by WordPress, such as wpdb->prepare()sanitize_text_field() and check_admin_referer() etc.

In addition, in order for the plugin to be used by users all over the world, internationalization (i18n) is necessary. We need to wrap all user-facing strings in the plugin with WordPress's translation function. This requires modifying our previous code:

1. Already specified in the plugin header comment Text Domain: my-first-plugin
2. Load the text domain. Usually added at the bottom of the main file:add_action( ‘plugins_loaded’, function() { load_plugin_textdomain( ‘my-first-plugin’, false, dirname( plugin_basename( FILE ) ) . ‘/languages/’ ); } );
3. Wrap the string. For example, change the title of the settings section to ( ‘自定义文本设置’, ‘my-first-plugin’ )Change the menu title to ( ‘我的插件设置’, ‘my-first-plugin’ )In this way, translators can translate the text accurately and efficiently. .po/.mo The file provides other language versions of these strings.

Prepare to release the plug-in to the official directory

If you want to submit your plugin to the official WordPress.org plugin directory, you need to follow a series of guidelines:
1. Code standards: Follow the WordPress coding standards.
2. File structure: In addition to the main file, it is usually also necessary to have README.txt(Describe the plugin, which is used on the catalog page.)uninstall.php(Dealing with the cleanup work when uninstalling plugins) etc.
3. SVN repository: The official directory uses Subversion (SVN) for version control, and you need to commit your plugin code to the designated SVN repository.
4. Metadata:README.txt It needs to be written in a specific format, including the plugin name, description, installation method, frequently asked questions, update logs, etc.

summarize

Through this tutorial, you have completed the full development cycle of a WordPress plugin: from creating the first file, writing header comments, implementing core functions using action hooks and filter hooks, to adding a configurable settings page for the plugin, and finally learning advanced knowledge such as security, internationalization, and release preparation. Although this plugin, which adds custom text to the end of articles, is simple, it covers the most core concepts and processes of plugin development. After mastering these basics, you can build increasingly powerful and complex plugins by exploring WordPress's vast system of hooks, shortcodes, custom post types (CPTs), and REST APIs. Remember, practice is the best way to learn. Trying to modify the code and add new features is the key to consolidating your knowledge.

FAQ Frequently Asked Questions

What should the main file of the plug-in be named?

The plugin main file can be named freely, but it must start with .php The end. Generally, for clarity and uniqueness, we use a name that is the same as the plugin folder name or one that describes the plugin's function, for example my-awesome-plugin.phpWordPress identifies plugins by reading specific comment blocks in the file header.

Why doesn't my plugin show up in the background menu?

This is usually caused by several reasons. Firstly, please check whether the plug-in has been successfully activated. Secondly, check add_menu_page() Or the user permission parameters (capability) in similar functions, to ensure that the currently logged-in user has the corresponding permissions (such as manage_optionsFinally, check whether your function passes the test correctly add_action(‘admin_menu’, …) Mount. Any PHP syntax errors may cause the entire plugin initialization to fail.

How to debug PHP errors in a plugin?

During the development phase, it is recommended to enable the debugging mode of WordPress. Open the file located in the root directory of the website. wp-config.php Check the file to ensure that the following settings have been enabled:
define( ‘WP_DEBUG’, true );
define( ‘WP_DEBUG_LOG’, true ); // 将错误记录到 /wp-content/debug.log
define( ‘WP_DEBUG_DISPLAY’, false ); // 不建议在页面上显示,以免破坏布局
In this way, the error information will be recorded in the log file, making it easier to find the problem. Please be sure to turn off the debugging mode before publishing the plug-in.

Where is the plugin option data stored?

Plugin usage add_option() Or update_option() The data saved by the function is stored in the WordPress database by default. wp_options The table (the table prefix might be different). Use it. get_option() Functions can read this data. For more complex data structures, custom database tables are sometimes created, but this requires more careful handling.

How can I make my plugin support multiple languages (internationalization)?

You need to use WordPress's translation function to wrap all user-facing strings. The most commonly used one is __(‘字符串’, ‘text-domain’) and _e(‘字符串’, ‘text-domain’)Then, use tools such as Poedit to extract these strings and generate a translation file. .pot Template file, and create the corresponding language (e.g. zh_CN.po and .moHere, "language files" refers to the translation files for the plugin. Finally, place the language files in the plugin directory. /languages/ Under the folder, and use it when the plug-in is initialized load_plugin_textdomain() The functions load them.