How To Create A WordPress Plugin

Last Updated on March 31, 2023 by 62 Comments

How To Create A WordPress Plugin
Blog / Tips & Tricks / How To Create A WordPress Plugin

WordPress Plugins allow users to easily modify, customize, and enhance any WordPress website. Instead of changing the core software WordPress is built on you can rather create a plugin to extend it. Using plugins allows you to have the most optimized WordPress installation all while maximizing how you use the software to begin with.

This article will walk you through the steps in creating a WordPress plugin.

What is a WordPress Plugin?

Here is the basic definition found on the WordPress Codex.

WordPress Plugin: A WordPress Plugin is a program, or a set of one or more functions, written in the PHP scripting language, that adds a specific set of features or services to the WordPress weblog, which can be seamlessly integrated with the weblog using access points and methods provided by the WordPress Plugin Application Program Interface (API).

Creating a Plugin

When creating a WordPress plugin there are some standards to uphold to when doing so. Below I’ll outline some key points to remember when creating your own.

Plugin Name

If you’re planning on making a plugin that doesn’t exist yet you will need to first determine its name. To be extra sure you will want to do a search in the WordPress Plugin repository. Some developers choose a name that describes more of what the plugin does so the end user can establish a quick connection with the name. The name itself can be multiple words.

Plugin Files

Typically a plugin lives within its own folder under wp-content/plugins/ inside your WordPress installation. There is usually at least one PHP file that is typically named after the plugin. So if your plugin was named amazing-plug then your PHP file name would most likely be amazing-plug.php. Using a unique name is crucial so no two plugins use the same name.

You can also choose to split your plugin into multiple files; similar to the way WordPress is built. Assets such as images, CSS, and JavaScript are common to see within installed plugins.

Readme File

Readme files are useful for other developers and users. Usually these files give a quick description of the plugin as well as sometimes offer change logs which indicate previous updates and maintenance announcements to users.

Home Page

If you plan to share you plugin with the WordPress community, having a dedicated home page would be wise. This page can be used as a place to download the plugin, report bugs, and announce updates to your user community.

Standard Plugin File

A plugin must contain a bit of meta information which tells WordPress what it is and how to handle it within your website. Plugins can be installed, deleted, activated, and inactivated. A standard header is introduced below to establish your plugin’s presence. The parameters shown will tell WordPress how to optimize it within your website and WordPress admin area.

<?php
/**
* Plugin Name: My Plugin Name
* Plugin URI: http://mypluginuri.com/
* Description: A brief description about your plugin.
* Version: 1.0 or whatever version of the plugin (pretty self explanatory)
* Author: Plugin Author's Name
* Author URI: Author's website
* License: A "Slug" license name e.g. GPL12
*/

The minimum WordPress needs to establish your file as a plugin is the line

Plugin Name: My Plugin Name

The rest of the information will be displayed within the Admin area under the Plugins section.

Programming the Plugin

Now the time comes to create our own demo plugin. I’ll be working on a local copy of WordPress using the our Divi 2.0 theme. You can follow along whichever method you prefer but to limit any downtime on your website I suggest you work locally or on a testing server. Our blog features other posts about installing WordPress locally if you are new to the concept. Find the links below depending on your platform.

Links:

For this tutorial I will be creating a plugin that creates a custom post type for our blog as well as establishes some other custom parameters. This plugin will be useful because we will be able to use it among any theme rather than just modifying one.

Plugin Scope

Our plugin will start with a simple PHP file. We will call this file custom-music-reviews.php. Within our file we will create a custom post type as well as define some new categories within that post type. The purpose of this plugin will be to write music reviews within specific genres without needing to touch code in the future. Each review will have a feature image, excerpt, rating, and genre type.

Starting Off

Assuming you have a local copy of WordPress ready to use, navigate to your wp-content folder inside of a code editor of your choice. Inside that folder you should see a folder called plugins. Inside of that folder create a new folder called custom-music-reviews.

With the folder created create a new file inside it called custom-music-reviews.php.

The path to the file should now be wp-content/plugins/custom-music-reviews/custom-music-reviews.php.

With your new file created we need to add some parameters in comment form like I explained earlier. For our plugin our parameters will look like this:

<?php
/**
* Plugin Name: Custom Music Reviews
* Plugin URI: https://www.elegantthemes.com/
* Description: A custom music review plugin built for example.
* Version: 1.0
* Author: Andy Leverenz
* Author URI: http://justalever.com/
**/

With this information added, save your file and navigate to your WordPress admin area. Click on Plugins on the left side navigation and you should now see our plugin available. Wasn’t that easy?

plugin-available

With our parameters in place our plugin becomes available to activate under “Installed Plugins”.

Even though our file is empty we can go ahead and activate the plugin. Go ahead and do that now. You’ll hopefully notice nothing different about your site with the plugin activate. If you do you probably typed the content above wrong or failed to close the comment.

Adding Our Plugin Code

With our file all set up and plugin active we can now add the inner workings of the plugin which we will be using for this tutorial.

Add the code below:

// Register the Custom Music Review Post Type

function register_cpt_music_review() {

    $labels = array(
        'name' => _x( 'Music Reviews', 'music_review' ),
        'singular_name' => _x( 'Music Review', 'music_review' ),
        'add_new' => _x( 'Add New', 'music_review' ),
        'add_new_item' => _x( 'Add New Music Review', 'music_review' ),
        'edit_item' => _x( 'Edit Music Review', 'music_review' ),
        'new_item' => _x( 'New Music Review', 'music_review' ),
        'view_item' => _x( 'View Music Review', 'music_review' ),
        'search_items' => _x( 'Search Music Reviews', 'music_review' ),
        'not_found' => _x( 'No music reviews found', 'music_review' ),
        'not_found_in_trash' => _x( 'No music reviews found in Trash', 'music_review' ),
        'parent_item_colon' => _x( 'Parent Music Review:', 'music_review' ),
        'menu_name' => _x( 'Music Reviews', 'music_review' ),
    );

    $args = array(
        'labels' => $labels,
        'hierarchical' => true,
        'description' => 'Music reviews filterable by genre',
        'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'trackbacks', 'custom-fields', 'comments', 'revisions', 'page-attributes' ),
        'taxonomies' => array( 'genres' ),
        'public' => true,
        'show_ui' => true,
        'show_in_menu' => true,
        'menu_position' => 5,
        'menu_icon' => 'dashicons-format-audio',
        'show_in_nav_menus' => true,
        'publicly_queryable' => true,
        'exclude_from_search' => false,
        'has_archive' => true,
        'query_var' => true,
        'can_export' => true,
        'rewrite' => true,
        'capability_type' => 'post'
    );

    register_post_type( 'music_review', $args );
}

add_action( 'init', 'register_cpt_music_review' );

This code above may look like a lot and almost seem like an unknown language to you if you’re new to WordPress but if not you’ll recognize this code as a Custom Post Type. In this case our custom post type is called music_review. The code is essentially telling WordPress to establish a new type of post within your theme. The post type has parameters that go along with it such as labels, arguments, and more. I won’t go into a ton of detail on how Custom Post Types work because I’ve already covered it within another article on Elegant Themes. Be sure to read it to gain a full understanding.

With our post type set up you can already see it active within the WordPress admin area.

Our custom post type is successfully implemented.

Lets take things one set further and include a custom Taxonomy called Genre inside our plugin. Think of a Taxonomy as a type of categorizing feature that is completely custom. WordPress already includes Categories and Tag support by default but developers can create custom taxonomies to extend their themes or plugins even further.
Read more about WordPress Taxonomies here.

Add the code below under the custom post type function we just added.

function genres_taxonomy() {
    register_taxonomy(
        'genres',
        'music_review',
        array(
            'hierarchical' => true,
            'label' => 'Genres',
            'query_var' => true,
            'rewrite' => array(
                'slug' => 'genre',
                'with_front' => false
            )
        )
    );
}
add_action( 'init', 'genres_taxonomy');

Registering a new Taxonomy is relatively easy. We have made the connection to our custom post type by using the
register_taxonomy() function which creates a new taxonomy called genres and assigns it to our post type music_review.

We need to add one more line to our custom post type to make everything sync up. Add this code just below the supports argument within the custom post type.

Here’s all our plugin code up until this point. For better legibility I’ve stripped our code of any comments we had prior to this.

function register_cpt_music_review() {

    $labels = array(
        'name' => _x( 'Music Reviews', 'music_review' ),
        'singular_name' => _x( 'Music Review', 'music_review' ),
        'add_new' => _x( 'Add New', 'music_review' ),
        'add_new_item' => _x( 'Add New Music Review', 'music_review' ),
        'edit_item' => _x( 'Edit Music Review', 'music_review' ),
        'new_item' => _x( 'New Music Review', 'music_review' ),
        'view_item' => _x( 'View Music Review', 'music_review' ),
        'search_items' => _x( 'Search Music Reviews', 'music_review' ),
        'not_found' => _x( 'No music reviews found', 'music_review' ),
        'not_found_in_trash' => _x( 'No music reviews found in Trash', 'music_review' ),
        'parent_item_colon' => _x( 'Parent Music Review:', 'music_review' ),
        'menu_name' => _x( 'Music Reviews', 'music_review' ),
    );

    $args = array(
        'labels' => $labels,
        'hierarchical' => true,
        'description' => 'Music reviews filterable by genre',
        'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'trackbacks', 'custom-fields', 'comments', 'revisions', 'page-attributes' ),
        'taxonomies' => array( 'genres' ),
        'public' => true,
        'show_ui' => true,
        'show_in_menu' => true,
        'menu_position' => 5,
        'menu_icon' => 'dashicons-format-audio',
        'show_in_nav_menus' => true,
        'publicly_queryable' => true,
        'exclude_from_search' => false,
        'has_archive' => true,
        'query_var' => true,
        'can_export' => true,
        'rewrite' => true,
        'capability_type' => 'post'
    );

    register_post_type( 'music_review', $args );
}

add_action( 'init', 'register_cpt_music_review' );

function genres_taxonomy() {
    register_taxonomy(
        'genres',
        'music_review',
        array(
            'hierarchical' => true,
            'label' => 'Genres',
            'query_var' => true,
            'rewrite' => array(
                'slug' => 'genre',
                'with_front' => false
            )
        )
    );
}
add_action( 'init', 'genres_taxonomy');

The only line that changed was the 'taxonomies' => array('genre') line within our custom post type. I added this line to tell our custom post type to connect to our new taxonomy and use it instead of the default category or tag structure WordPress comes installed with.

If you’ve made it this far you can now visit your WordPress admin area and see your new custom post type and taxonomy(Genres) present. Congrats!

custom-pt-and-tax-available

Our custom post type and taxonomy are successfully implemented. Here we can add a new Music Review which contains various types of genres decided upon by the user.

Getting Our Code To Output

Below I’ll try adding a new music review. You should see the new Genres section that we set up with our custom Taxonomy. With some data entered I’ll publish the post.

new-music-review

Create a new music review as an example.

At this point we have our functionality set up within our plugin.

In order to make things effortless we will rely on the plugin to create a new page called Music Reviews. The page will be referenced by our plugin and output any new music reviews the user posts. We are doing this so the user doesn’t have to edit a single line of code.

Tying it All Together

Our code now works but we should create a page that will use

// Function used to automatically create Music Reviews page.
function create_music_review_pages()
  {
   //post status and options
    $post = array(
          'comment_status' => 'open',
          'ping_status' =>  'closed' ,
          'post_date' => date('Y-m-d H:i:s'),
          'post_name' => 'music_review',
          'post_status' => 'publish' ,
          'post_title' => 'Music Reviews',
          'post_type' => 'page',
    );
    //insert page and save the id
    $newvalue = wp_insert_post( $post, false );
    //save the id in the database
    update_option( 'mrpage', $newvalue );
  }

And finally we need to create our Music Reviews page once the plugin is activated. Adding the code below initiates the function we just wrote above ( function create_music_review_pages(){…}).

// // Activates function if plugin is activated
register_activation_hook( __FILE__, 'create_music_review_pages');

Testing

Our plugin should be ready to test at this point. Lets create an example music review and see what outputs.

new-music-review-test

Create another music review to verify our plugin is working correctly.

If you click View Music Review once the post is published you should be taken to a screen which looks similar to the image below. Your theme and styles may vary…

the-single-review

The single page music review template

You may notice that I modified the menu to include our new Music Reviews page. Doing this gives us easy access.

adjust-menu

Adjusting primary navigation to include “Music Reviews” page

With your menu in place and saved click on Music Reviews to see all the posts we have made so far.

Based on the page template supplied by your theme the Music Review should output all together and be clickable through to the single review template. You will probably notice that the music review I posted earlier has output as well as the one we just created.

music-reviews-list

Our music reviews on the “Music Review” page

Our feature image, title, genre, and review all have posted successfully. Our plugin works!

To verify, you can deactivate the plugin and reinstall it or activate it. Upon doing so a new Page called Music Reviews should be created. You can delete or reuse the one from before if there are duplicates but there should be only one “Music Reviews” page. We could have added a function to delete and restore this page within our plugin but I wanted to keep things as simple as possible.

Finish

Our plugin is a relatively simple one. You can extend it so much further by including it’s own predefined templates, custom widgets, more taxonomies and so much more. Creating a plugin is no easy feat. You will want to plan your plugin before even moving to development. Knowing what you can an can’t do with WordPress before coding your own plugin is a crucial step to developing a quality one. The plugin create in this tutorial is meant to teach by example. There are better standards to follow and more useful practices to endure. Be sure to read the WordPress Codex and get familiar with the WordPress Plugin API. If a plugin isn’t out there and you need custom functionality for your website then I stronger encourage trying to create your own!

All album covers and rights belong to their creators. Elegant Themes does not own or have any relation to the artists being reviewed in this tutorial. Imagery and titles were used by example only.

Article thumbnail image “plug” illustration by RAStudio / Shutterstock.com

Divi

Want To Build Better WordPress Websites? Start Here! 👇

Take the first step towards a better website.

Get Started
Divi
Premade Layouts

Check Out These Related Posts

Splice Video Editor: An Overview and Review

Splice Video Editor: An Overview and Review

Updated on March 10, 2023 in Tips & Tricks

Video is a valuable form of content for social media. Unfortunately, creating quality videos is usually a long process that involves moving mobile footage to a desktop app for editing. However, mobile editing is on the rise. Apps such as Splice Video Editor make it possible to efficiently create...

View Full Post
How to Use Font Awesome On Your WordPress Website

How to Use Font Awesome On Your WordPress Website

Updated on September 16, 2022 in Tips & Tricks

When given the choice between using a vector icon or a static image, it’s a good idea to go with the vector. They’re small and fast to load, and they can scale to any size without a loss of resolution. Font Awesome is a superb library of vector icons that you can use on your websites,...

View Full Post

62 Comments

  1. I’m really not getting the last point of your tutorial. How the hell do I show those music reviews on my site? I need to make “a” page… What kind of page? Where? Not clear at all. The beginning is great, but the last part of the tutorial sucks.

    Can you explain how or where I should “make” that page?

  2. Thank you so much Andy!! for sharing a grate idea . can you help me to create a contact form plugin with dropzone

  3. Great article. Looking for more from you Andy.

  4. sir can u plz help me ?

    when i click on view post message comes like ->

    “Oops! That page can’t be found.”

    i am using my localhost

  5. great article thanks.

  6. Nice article, I’m a beginner in WordPress and this article helps a lot. Thanks!

  7. Great read! Thanks for putting this together. I have a client that would like to get a feature on their site that another site appears to have custom coded. If I can access the source code, I may try to make my own version of the feature as a plugin. Hopefully it will work!

    • how to call inserted value in view page help me ?

  8. I’ve followed the tutorial and added my page(s) but get “Oops! That page can’t be found.”

  9. I have tried this tutorial, every things seems to be working fine, but when view page link is launched “Oops! That page can’t be found.” error is displayed
    Here is how the url look
    http://localhost/mysite/music_review/mama-love/

    However if i search post title it is displayed in search result but clicking on the title take you to the above link but with error message.

    Unable to resolve this any help would be greatly appreciated.

    • Same problem here 😐

      • Likewise, just noticed this after posting my comment

  10. Not sure I understand the ‘create a page’ part. Isn’t it just showing the music reviews using the archive.php template given that you have ‘has_archive’ set to true when you register the post type?

    How would that music review ‘page’ suddenly become the archive?

  11. Hi Andy,

    Great read! Thanks for putting this together. I have a client that would like to get a feature on their site that another site appears to have custom coded. If I can access the source code, I may try to make my own version of the feature as a plugin. Hopefully it will work!

  12. Any help would be greatly appreciated !
    (please see my last post above)
    Many thanks.

  13. Hi Andy
    Great article.
    But as I’m a complete newbie at this…
    Please Help ~ I’ve got a bit lost !

    Your code seems to work OK up to the section prior to: Tying it All Together

    Q1: So in what file do I add the code/function shown under the heading: Tying it All Together

    ie: Where do I add this (function) code:
    // Function used to automatically create Music Reviews page.
    function create_music_review_pages()

    …etc, etc…

    and this code:
    // // Activates function if plugin is activated
    register_activation_hook( __FILE__, ‘create_music_review_pages’);

    a: Do I add them to the end of: custom-music-reviews.php
    Or
    b: Do I have to create another new file ?

    I’ve tried (a) but It doesn’t seem to make any difference !

    Q2: I’m also confused about adding the new ‘Music Reviews’ menu:

    Your info says:
    ‘With your menu in place and saved click on Music Reviews
    to see all the posts we have made so far.’

    So I added the ‘Music Reviews’ menu:
    Which is displayed in the left-column of my theme,
    but when I click it, it just shows the text of the ‘Sample Page’ ! ie…

    ‘Sample Page
    This is an example page. It’s different from a blog post because… etc, etc…’

    Q3: I’ve entered 3 test ‘Music Reviews’
    But I can’t get any of them to display, unless I log in, & click on the
    [View Music Review] button, on the >Edit Music Review< page.

    …So how do I display/view each of my 'Music Reviews' pages ?

    ie: as per your images: the-single-review.png & music-reviews-list.png

    Please help, many thanks.

    • Figure out that problem? Was wondering as well where register_activation_hook goes

  14. Sorry I think even WP codex also uses 2 dimensional array, so disregard 🙂

  15. It’s a nice tutorial, but I don’t know if it’s helpful to all, since this tutorial is aimed at everyone even those who don’t know programming e.g. “This code above may look like a lot and almost seem like an unknown language to you” using a 2 dimensional array is an overkill in this case, it confuses people. You could’ve done something simpler with just one array.

  16. When I tried this out, the page it automatically creates isn’t Published, it’s Scheduled. How to fix?

  17. Hi Andy,

    I have used your tutorial and plan to modify it just a little to write content into a jquery style accordian type widget. I followed it closely and it appears that everything works fine except for the last thing. The content is not showing up in my theme. I’m using html5_blank.

    All the other functionality is there, creating a new post, category (taxonomy), activating/deactivating the plug and creating the page dynamically. It shows the comment section in the page, but not the content nor featured image. I have to be missing something simple, but have no idea what it is. Any help or advice you can give would be greatly appreciated. I can provide whatever info you need, as well as logins or code.

    Thanks!

    • Nevermind. 🙂 I had to set the permalinks to default, then back to custom to get it to work.. Weird.

  18. Hi,
    I’m a physiotherapist and good at helping people, but not that known about creating a plugin.;)
    I’m making a new site (wordpress, divi theme), where I would like a plugin compatible with Buddypress members. It would be great if I (administrator or editor) could point out an exercise per member. So the member can see what exercises he has to do on his own profile. I’ve a database on vimeo with video exercises. I would like to be able to link one or more videos to a single member. So the member can only see his own exercises. It would be even greater if I could give comments, like how often the member has to do them.

    Can somebody help me?

  19. This tutorial is very complete, sometimes I think that we should not always depend on the plugin at wordpress.org, occasional we should be able to make. thank you

  20. Great tutorial, could follow each step in my local wordpress and replicate it. Thanks for sharing this.

  21. Hello. Great tutorial!

    But I need to add some media (images) to each post item (imagine I want to add more than one image per music album). How could I do this without adding them to the editor?

    Thanks in advance

  22. Hi , Great tutorial perfect to create custom content plugins. Just wanted to let you know you forgot to close the php at end of plugin “?>” I could mistaken and this is not needed?

  23. great article. this is very easy and helpul for newcummer.
    thanx Andy!

  24. I didn’t know that I can make a plugin this easy. Thanks for the code. ^_^

    I have a question however, using this, assuming I created a custom post type (CPT) “Video Management”, when I click Add New the page editor for my CPT will show, how do I customize this page? I want to put a completely different look and feel of the editor.

    Thanks!

  25. This is exactly what I was looking for. Starting to develop my first plugin for wordpress and this is a very good starting point for me. Thanks for this great, strait forward tutorial!

  26. Thanks . This really helped.

    Plugin is working . But how can i add new input fields to the “Add New ” screen. How to add a custom form to the plugin

  27. Thanks so much for this Andy – I’m currently playing with this code in an attempt to create my very first plugin. Very exciting!

  28. HI,

    Great post, thanks.

    Quick question:

    If I click ‘View Music Review’ on the Edit page it displays the page OK, but my ‘Music Reviews’ page doesn’t list the reviews that I’ve published – is there a step missing or do I have to add some code somewhere?

    FYI I’m using the Twenty Fourteen theme on a local install of WP.

    • I had the same issue , How I fixed this – Go to the settings page -> Permalinks and select “post name” and save the page and this should fix your problem. If you are already on “post name” then change it to “default” save the page and then after save turn it back to “post name” this forces wp to re make the .htaccess page and should fix the issue.

      • this was very helpful. thank you

  29. nice tutorial but please you explain what is “mrpage” inthe code? and after I try to add post the page that create with this plugin wont show any output.

    thank you

  30. Excellent Blog Post. Actually I am understand after read the post. How to make WordPress plugin. It’s my dream How I will be WordPress Developer. Thank you Andy Leverenz

  31. Great article , i also want creat wordpress plugins , this post is very usfull. Thank for this post.

  32. Perfect guide on how to create a standard WordPress plugin.

  33. Thanks for the awesome article and inspiration!I knew I should have taken some programming classes in high school and college (despite my name) haha! Better late than never!

  34. What a great article. Just what i needed to start developing some of all my ideas! 🙂

  35. Super-cool! Thanks!
    How do I add existing taxonomies, like tags?

  36. Another super tutorial @Andy Leverenz – was hoping you’d cover how to activate the Divi Page Builder with the custom post type (had asked the same question on your last post) – if there was a way to activate the Divi builder on custom post types then creating page templates would solve creating custom meta fields/boxes for output to show on the front end.

    This support post/ticket starts to show the tweaks required to the et-pagebuildder.php file… what I can’t figure out if the entire contents of the file are added to a child theme or just the code shown in this ticket: https://www.elegantthemes.com/forum/viewtopic.php?f=187&t=267198 – user: @thinklabs shared the tweak but would love some guidance on whether the child theme should have all the code or just what was shared.

    Thank you so much, between your posts and @Brad Dalton’s tutorial site, I’ve come a long way in understanding the possibilities of WP and Divi.

    Looking forward to your next post 🙂

  37. Another great post Andy !!! Very valuable information with point to point tutorials.

    • Thank you!

  38. Awesome 🙂

  39. So delicious! opening up the community horizon…! But we need some CSS to compliment the developers code. Thank you very much Andy!

    • Agree! I could have styled up the implemented plugin but unfortunately that wasn’t the purpose for this tutorial. Maybe for future articles I’ll include this.

      Thanks!

      • Well, I was expecting too how to add css to the plugin. 🙂
        Do you have any link we can use to do it?

        Thanks! Great tutorial! 🙂

  40. I love this tutorial…

    • 🙂

    • Great share Brad. Thanks!

  41. This is awesome. Just what I needed to spur me into making a plugin I have been thinking about!

    • Glad I could inspire you Joseph. Hope you have success with the plugin. Thanks for the comment!

  42. Another great tutorial!

    • Thanks Clay

  43. Great article, very extensive with usable examples. Will give it a shot to get some more experience with WP customization.

    Is it possible to make a similar writeup for a plugin that alters existing content/pages rather than creating a custom post type?

    Thanks for sharing!

    • This may be possible. Plugins allow you to do a huge number of things so tailoring it to your own specific needs is what makes them so powerful.
      Thanks!

      • Hi Andy, very nice post!, I created the plugin and when I see shows “the page can not be found”. Can you help me? ty !

Leave A Reply

Comments are reviewed and must adhere to our comments policy.

Get Started With Divi