How to Create a WordPress Plugin Step-by-Step
WordPress has a massive collection of plugins available that introduce custom functionality. What’s more, plugins can add new features to your WordPress website without having to change the core code.
While there are tons of free and premium plugins to choose from, there may be occasions when you need specific WordPress functions that aren’t available. For that, you may need to build your own WordPress plugin.
In this WordPress plugin tutorial, you’ll learn the steps to create a WordPress plugin. We will also go over the best coding and plugin creation practices and standards.
Additionally, this article will cover the differences between a plugin and a theme and how they work on the WordPress platform.
What You’ll Need to Make a WordPress Plugin
Here is what you will need to create a WordPress plugin:
- A text editor
- FTP access to your hosting account
- A working WordPress installation
You will need a text editor to write the plugin code. Some of the most popular HTML editors include Notepad++ and Atom.
After installing the text editor, connect it to your FTP server for code modification. We have a guide on how to connect to FTP with Notepad++ if you need assistance.
Next, configure an FTP client to upload the plugin file to your website. We recommend using the FileZilla FTP application as it is straightforward to set up.
Lastly, make sure you have a working and up-to-date WordPress installation. There are several ways to update the WordPress core files if you have disabled automatic updates. Back up your WordPress files before updating the site to avoid data loss.
Alternatively, consider installing WordPress locally. This method doesn’t require a live website with a domain name and a hosting plan, so you can test your plugin without visitors seeing it right away.
Having a basic knowledge of PHP will benefit your plugin development process. You’ll need to write a custom function and call existing WordPress core functions. At the very least, you should be familiar with PHP naming conventions and file structuring.
WordPress Plugins vs WordPress Themes
WordPress site functionality can be changed through plugins and themes.
WordPress themes have a functions.php file stored in the /wp-includes/ folder, which lets you add custom code for new functions.
While this method works for minor alterations, it is impractical for implementing major changes that affect the entire website.
That’s because the functionality stored in the functions.php file depends on whether the theme is active or not. Disabling the WordPress theme will revert the changes made in the said file and trigger an error when the site calls for the missing functions.
Unless you’re using a child theme, updating the theme will also overwrite the functions.php file, forcing you to manually restore the custom WordPress code.
That’s why building a custom plugin is helpful. Doing so facilitates the modification of default WordPress behavior to fit your needs.
You can add WordPress plugins to any WordPress installation. Features introduced by the plugin will remain functional even if you switch themes. Plus, updates won’t overwrite existing functions, saving you time and effort.
What are WordPress Hooks?
WordPress plugins interact with the core code using hooks. There are two different types of WordPress hooks:
- Action hooks ‒ add or remove functions.
- Filter hooks ‒ modify data produced by functions.
Actions and Action Hooks
An action is a PHP function called through a specific action hook when a user visits a WordPress web page. Web developers can add their own functions to the list of actions or remove pre-existing ones by adding the wp_head() action hook script before the closing tag (</head>) of any page.
Action hooks are contextual, which means that not all WordPress pages call for them. The WordPress Plugin Action Reference page provides a complete list of action hooks and the contexts within which they are called.
Adding Functions to an Action Hook Using add_action()
Adding functions to an action hook in a plugin file requires calling the add_action() function with at least two parameters.
// Hook to the 'init' action, which is called after WordPress is finished loading the core code add_action( 'init', 'add_Cookie' ); // Set a cookie with the current time of day function add_Cookie() { setcookie("last_visit_time", date("r"), time()+60*60*24*30, "/"); }
The third optional parameter states the priority of the said function. The default priority is 10, putting the custom function after any of the built-in ones.
The first parameter is the name of the action hook you want to attach the callback to, while the second parameter contains the name of the function that you want to run.
The fourth parameter, which is also optional, contains the number of arguments or parameters the custom function can take. The default value is 1.
Example of Plugin Code to Display Text After the Footer of Every Page
This example plugin calls the wp_footer() action hook before the closing </body> tag of every page, and adds a new function named mfp_Add_Text(). Since it’s part of a plugin, the function will work even after switching themes.
Save this example as a PHP file and upload it to the plugins folder.
<?php /* Plugin Name: Add Text To Footer */ // Hook the 'wp_footer' action hook, add the function named 'mfp_Add_Text' to it add_action("wp_footer", "mfp_Add_Text"); // Define 'mfp_Add_Text' function mfp_Add_Text() { echo "<p style='color: black;'>After the footer is loaded, my text is added!</p>"; }
The following screenshot shows the plugin in action after activating it via the WordPress admin panel:
Important! PHP evaluates the entire script before executing it. Writing add_action() calls at the top of the file in their execution order and then defining your functions in the same order below will make the file easier to read.
Removing Functions From an Action Hook Using remove_action()
To remove an action from an action hook, write a new function remove_action() and then call the function you have written using add_action().
The remove_action() function should also contain at least two parameters.
// Hook the 'init' action, which is called after WordPress is finished loading the core code, add the function 'remove_My_Meta_Tags' add_action( 'init', 'remove_My_Meta_Tags' ); // Remove the 'add_My_Meta_Tags' function from the wp_head action hook function remove_My_Meta_Tags() { remove_action( 'wp_head', 'add_My_Meta_Tags'); }
The first parameter is the name of the action hook the function is attached to, while the second parameter contains the name of the function that you want to remove.
The third optional parameter states the priority of the original function. It must be identical to the priority that was originally defined when adding the action to the action hook. If you didn’t define a priority in the custom function, don’t include this parameter.
In the next example, we’ll prevent the extra footer text from appearing on Monday posts.
One way of doing this is by using the PHP date() function to get the current day, followed by conditional tags to check if it is Monday. After parsing the information, the page will execute the remove_action() function in every post published on Mondays.
<?php // Hook the 'wp_footer' action, run the function named 'mfp_Add_Text()' add_action("wp_footer", "mfp_Add_Text"); // Hook the 'wp_head' action, run the function named 'mfp_Remove_Text()' add_action("wp_head", "mfp_Remove_Text"); // Define the function named 'mfp_Add_Text('), which just echoes simple text function mfp_Add_Text() { echo "<p style='color: #FFF;'>After the footer is loaded, my text is added!</p>"; } // Define the function named 'mfp_Remove_Text()' to remove our previous function from the 'wp_footer' action function mfp_Remove_Text() { if (date("l") === "Monday") { // Target the 'wp_footer' action, remove the 'mfp_Add_Text' function from it remove_action("wp_footer", "mfp_Add_Text"); } }
Filters and Filter Hooks
A filter is a PHP function called by a specific filter hook that modifies data returned by existing functions. Like action hooks, filter hooks are also contextual.
The complete list of filter hooks and contexts they are called in are available on the WordPress Plugin Filter Reference page.
Adding Filters Using add_filter()
Adding a filter function to a filter hook within a plugin file requires calling the add_filter() function with at least two parameters.
// Hook the 'the_content' filter hook (content of any post), run the function named 'mfp_Fix_Text_Spacing' add_filter("the_content", "mfp_Fix_Text_Spacing"); // Automatically correct double spaces from any post function mfp_Fix_Text_Spacing($the_Post) { $the_New_Post = str_replace(" ", " ", $the_Post); return $the_New_Post; }
The first parameter is the name of the filter hook you want to add the callback to, while the second parameter contains the name of the function you want to run when the filter is applied.
The third optional parameter states the priority of the said function. The default priority is 10, putting the custom function after any default ones.
The fourth optional parameter contains the number of arguments or parameters the custom filter function can take. The default value is 1.
Example Plugin to Alter a Post Excerpt
WordPress has a function that retrieves post excerpts named get_the_excerpt(). It is also a filter hook. Adding this filter after retrieving the excerpt will alter the text before the WordPress site displays it.
The following example plugin defines a filter function that takes the excerpt as its only input parameter, adds some text before it, and returns the new value every time the script calls the get_the_excerpt() function.
As the return value of the get_the_excerpt() function is the actual excerpt text, the plugin will automatically input the new value as the function’s parameter $old_Excerpt when called using add_filter(). The function the plugin defines must return the new value.
<?php /* Plugin Name: Add Excerpt */ // Hook the get_the_excerpt filter hook, run the function named mfp_Add_Text_To_Excerpt add_filter("get_the_excerpt", "mfp_Add_Text_To_Excerpt"); // Take the excerpt, add some text before it, and return the new excerpt function mfp_Add_Text_To_Excerpt($old_Excerpt) { $new_Excerpt = "<b>Excerpt: </b>" . $old_Excerpt; return $new_Excerpt; }
Removing Filters Using remove_filter()
Removing a filter is much simpler than removing an action as WordPress lets you call the remove_filter() function without defining a new one.
In the following example, we’ll remove the additional excerpt text if the current day is Thursday. We’ll use the remove_filter() function with at least two parameters.
The first one should contain the filter hook the function is attached to. The second parameter should be the name of the filter you want to remove. Add a priority parameter if you defined it when creating the function.
// Hook the get_the_excerpt filter hook, run the function named mfp_Add_Text_To_Excerpt add_filter("get_the_excerpt", "mfp_Add_Text_To_Excerpt"); // If today is a Thursday, remove the filter from the_excerpt() if (date("l") === "Thursday") { remove_filter("get_the_excerpt", "mfp_Add_Text_To_Excerpt"); } // Take the excerpt, add some text before it, and return the new excerpt function mfp_Add_Text_To_Excerpt($old_Excerpt) { $new_Excerpt = "<b>Excerpt: </b>" . $old_Excerpt; return $new_Excerpt; }
Now that you have a basic understanding of hooks and filters, we’ll create a simple WordPress plugin that will add a new page with a link on the admin control panel.
Important! Using a WordPress staging site to test new plugins will help you avoid errors that may cause downtime. There are two ways to build a staging environment ‒ manually or by using a plugin like WP Staging. Alternatively, install WordPress locally on your computer.
Step 1 – Storing the Plugin
The first step to creating a new plugin is to make a folder for its files. The folder’s name should be unique and descriptive. Check the other plugin folders’ names within /wp-content/plugins/ to make sure that the new name isn’t in use already.
Use an FTP client to connect to your hosting account to facilitate the file upload process. Navigate to wp-content -> plugins from the main WordPress directory. Then, create a new folder named my-new-plugin in the plugins folder.
Practicing file management during WordPress development will make the process much easier in the long run. Divide the files into subfolders based on their functionality.
For example, save the CSS, PHP, and JavaScript files in separate folders. As you develop your custom WordPress plugin, it’ll be easier to locate specific files when everything has a dedicated directory.
Step 2 – Creating the First File
The main plugin file will contain the information WordPress requires to display your plugin in the plugin list where you’ll be able to activate it.
Create a new PHP file called my-first-plugin.php in the folder you made earlier. This main plugin file will contain header comments with additional information for WordPress to read or display.
Then, right-click the file and select View/Edit to add the following code using an HTML editor:
<?php /* Plugin Name: My First Plugin Description: This is my first plugin! It makes a new admin menu link! Author: Your Name */
You can refer to this PHP manual to understand why the closing tag ?> isn’t necessary here.
Save the file. Then, navigate to the Plugins section of your WordPress dashboard. If WordPress has read the new file correctly, you’ll see My First Plugin on the list:
Step 3 – Writing the Plugin Functions
Before we begin writing the functions for the plugin, it is highly recommended to give all files, functions, and variables a unique prefix in their name to avoid any conflicts with other plugins. In our example, we’ll be using the prefix mfp, which is short for My First Plugin.
Create a new folder named Includes in the plugin’s main directory. We’ll use it to store supporting files used by the main file. In this folder, create a PHP file and name it mfp-functions.php. Give it the opening <?php tag on the first line.
This new file will contain all of your plugin’s functions.
We’ll have to include mfp-functions.php in the main plugin file to allow the other plugin files to use the functions it defines. Use require_once to ensure the plugin only works if the functions file is present.
Edit my-first-plugin.php as shown below. Then, save it and upload the file once again, overwriting the previous version when asked.
<?php /* Plugin Name: My First Plugin Description: This is my first plugin! It makes a new admin menu link! Author: Your Name */ // Include mfp-functions.php, use require_once to stop the script if mfp-functions.php is not found require_once plugin_dir_path(__FILE__) . 'includes/mfp-functions.php';
The WordPress function plugin_dir_path(__FILE__) lets you include files from your plugin folder, giving the full path to the directory that stores the new plugin.
Now, return to the mfp-functions.php file in the Includes directory. As our plugin will add a new top-level link to the navigation menu of the admin control panel, we’ll use a custom function named mfp_Add_My_Admin_Link(). Add the code block below to the mfp-functions.php file:
<?php /* * Add my new menu to the Admin Control Panel */ // Hook the 'admin_menu' action hook, run the function named 'mfp_Add_My_Admin_Link()' add_action( 'admin_menu', 'mfp_Add_My_Admin_Link' ); // Add a new top level menu link to the ACP function mfp_Add_My_Admin_Link() { add_menu_page( 'My First Page', // Title of the page 'My First Plugin', // Text to show on the menu link 'manage_options', // Capability requirement to see the link 'includes/mfp-first-acp-page.php' // The 'slug' - file to display when clicking the link ); }
Important! Group similar functions together and add a description above each of them using a multi-line comment. Doing so will make future plugin updates and debugging easier.
mfp_Add_My_Admin_Link() uses the built-in WordPress function add_menu_page() with at least four parameters in the following order:
- Page title ‒ the page name displayed on the browser tab.
- Menu title ‒ the text used for the menu item. In our example, it is the plugin’s name.
- Capability ‒ user capability requirement to view the plugin menu. Here, only users with the manage_options capability can access the linked page.
- Menu slug ‒ the file to use to display the actual page. We’ll create the linked-to mfp-first-acp-page.php file in the Includes folder in the next section.
- Function (optional) ‒ the function that outputs the page content.
Attaching the custom function using add_action() allows the plugin to call the action hook under certain circumstances. Adding admin_menu as the first parameter will call the function when a user accesses the admin menu. Meanwhile, mfp_Add_My_Admin_Link is the function that will be run as it is specified as the second parameter.
Finally, upload the mfp-functions.php plugin file to the Includes folder.
Step 4 – Creating the Plugin Admin Page
After defining the plugin’s functions, it’s time to build the page that the menu button will take us to. Create a new PHP file named mfp-first-acp-page.php in the Includes subfolder and add the following code to it:
<div class="wrap"> <h1>Hello!</h1> <p>This is my plugin's first page</p> </div>
When creating admin pages, WordPress recommends enclosing your own HTML with a <div> tag and giving it a “wrap” class to ensure that all your content appears in the correct place. Doing so also helps reduce clutter in the code.
Finally, navigate to the Plugins section on your WordPress dashboard and activate the new plugin. If the process is successful, the admin panel link of your very first plugin will appear at the bottom of the navigation menu.
Congratulations – you have successfully created your first WordPress plugin.
If you built the plugin on a staging site, you’ll need to install the plugin on the live site. The following steps will show you how to do it:
- In FileZilla, right-click the my-new-plugin folder and select Download. Then, compress the files into a ZIP archive.
- Navigate to the Plugins menu from your WordPress dashboard. Then, click Add New.
- Click Upload Plugin and select the ZIP file of your plugin.
- Select Install Now to start the installation process.
Suggested Reading
Wondering what languages WordPress plugins are written in? Learn more in the following guides:
What Is HTML
What Is CSS
What Is JavaScript
Great Standards and Practices When Creating Custom Plugins
As your site’s needs continually evolve, you’ll need to revisit the plugin’s code to implement updates and security patches.
With this in mind, follow the best practices for plugin development right from the beginning. Doing so will make the entire process easier for you and any web developers you may work with in the future.
Additionally, refer to the best WordPress plugin examples for inspiration. Look at their source code, how they organize their folders, and other practices to apply when building WordPress plugins.
Here are some of the best coding and plugin development practices to help the creation of your first WordPress plugin:
- Develop and test WP plugins in a staging environment. This way, there’ll be no risk of breaking the site if a plugin has faulty code.
- Build a logical folder structure. Create subfolders for each functionality and divide the code into separate files based on their purpose or language type to avoid clutter.
- Name each file, folder, and element with caution. Use unique prefixes, so they don’t clash with the file names of other plugins or the WordPress core.
- Add comments to label each function. Doing so allows you and other developers to understand your code when updating or debugging it.
- Create documentation. This practice is particularly beneficial if you create plugins with complex functionality for a large number of users.
- Use version control software to track changes made in your code. Knowing who added what will help prevent clashes between updates and reduce the number of bugs.
- Refer to the WordPress Codex for language-specific coding standards. Make sure to comply with them when collaborating on a project.
- Activate WP_DEBUG or use a debugging tool when developing plugins. Doing so will make locating bugs easier, speeding the overall plugin building process.
Conclusion
Developing a custom plugin is a way to add functionality to a WordPress site that currently available plugins don’t offer. It can be a simple plugin that implements minor alterations or a complex one that modifies the entire site.
To recap, here are the steps to create a WordPress plugin from scratch:
- Create a folder to store the plugin files.
- Create the main file for your plugin.
- Add code to multiple files for plugin functions.
- Build the plugin’s admin page.
Like with any other skill, it takes time to get good at making WordPress plugins. With enough practice, you’ll be able to create plugins and make them available for download on the WordPress plugin directory or even sell them on one of the marketplaces.
We hope this article has taught you how to make a WordPress plugin. If you have any questions or remarks, feel free to leave a comment.
Create A WordPress Plugin FAQ
Can You Make Money Making WordPress Plugins?
Yes, you can either sell plugins through your own website or on a plugin marketplace.
Who Can Build a WordPress Plugin?
Anyone who knows how to code can create a WordPress plugin. You can use a theme to create a plugin, if you know basic PHP.
Are WordPress Plugins Written In PHP?
WordPress plugins are often written in PHP, but you will also need to know some basic HTML and CSS to properly manage the plugin’s output.
Comments
November 25 2017
Pretty nice and simple tutorial, helped me a lot to get fast into WP plugin creation. There's just one thing that didn't work for me: I did everything just like you did but my WordPress couln't find my admin page. For me the problem was in step 3 at the "add_menu_page()" function. The problem was the 4th parameter 'includes/mfp-first-acp-page.php', I changed it to 'my-first-plugin/includes/mfp-first-acp-page.php' and it worked like it should. I don't know if it's caused by a WP-Update or something else. And thanks again for your tutorial.
August 22 2018
Thanks for adding this comment. I had the same problem, easy fix!
January 07 2019
Thanks, I had the same issue and I was continuously checking where I had made the mistake, but after looking at your comment, I had to change the root directory to my-first-plugin/includes/mfp-first-acp-page.php. I think they should change the code because when I didn't get the output I was disappointed that I made some mistake. You are a life saver Thanks a lot.
January 07 2019
You are a life saver
December 21 2017
Nice tutorial. Like @Hoargarth mentioned, I had to add the name of the plugin in the 4th parameter value for add_menu_page in order for it to work. In your current example it was trying to display the page in the frontend. Great tutorial overall. Simple and to the point.
September 12 2018
Great first start in building a plugin !!
March 11 2019
I have read the article and it was very helpful for me, thank you for this wonderful article. Also, I would like to add that my favorite plugin "Woocommerce", it's my favorite because here there are various types of customization like we can add discount coupons, select color attributes, we can add a variable product etc. It's a very useful plugin for new developers who are targeting E-commerce development.
February 20 2020
We are getting the 404 error. After click on created menu.
March 12 2020
Hi RajJes, Try these 404 error fixes to get rid of the error :)
April 21 2020
This is really good. Now that I have my plugin I would like to create a premium version. How about a tutorial on how to create a paid version that is different and updates automatically, keeping it separate from the free version. There doesn't seem to be any information about how to do this on the web. Thanks
April 23 2020
Hey, Steve, glad you liked the article, and thanks for the suggestion!
May 30 2020
Very good tutorials guard. Thank you very much
September 19 2021
Great Article Well Explained