Creating my plugin

So this is a small self project that I am using to kind of reteach myself how to create a plugin. My main focus is not only to create a plugin but to create it right(or at least what right looks like to me). Because I have a huge case of picking up steam then backing off of things this will good chance be a multi-part tutorial.

My end goal is to create a plugin that enables a user to create baseball card for their website, it will mirror my CodePen that I have created for a previous project. My plan of attack is to create it using OOP as the basis and to use React to build the a block to show the baseball card. Also will need a css and js prepocessor such as webmix or vite to process it and to use either a sass or postcss for the basis.

Project Requirements

  1. Use up to date PHP practices such as OOP and PHPCS to validate code
  2. Create a custom post type
  3. Use a css and js bundler such as webmix, gulp, or vite
  4. Build out a block to show the player card
  5. Build out a page to index player cards.

Part 1

  1. Add Header Requirements
  2. Add Namespace and Autoloading
  3. Register Custom Post Type

Add Header Requirements

Why: To use your plugin on WordPress there is certain information that must be included in your plugin to properly show in the plugin dashboard. The better the header requirement is thought out and executed the easier it is for the user to understand and use the plugin.

To start out you can either create a directory or create a file with your plugin name, it’s best practice to create a directory with the main file being the same name as the directory. So to get our plugin ready we will create a directory inside of the WordPress plugin directory and name it player-card. Then inside of that directory we will name a php file with the same name player-card.php. This will be our main file for the plugin, you should then be able to find the plugin from the root like this


After the main file is created we will start setting up the header requirements using WordPress header requirement standards.

If we want to get the minimum viable product(MVP) up and running the only things that we need/should to include is:

 * Plugin Name: Player Card

This will give the user the name of your plugin. The name can be whatever you want it to be, but for our example we are using Player Card.

Although that will work, it’s doesn’t make for a very good user experience. A good plan of action is to try to fill out as many of the Header Fields as you can. You can also incorporate some PHPDocblock into your header as well.

 * Plugin Name
 * @package           PluginPackage
 * @author            Your Name
 * @copyright         2019 Your Name or Company Name
 * @license           GPL-2.0-or-later
 * @wordpress-plugin
 * Plugin Name:       Plugin Name
 * Plugin URI:
 * Description:       A short description of the plugin, as displayed in the Plugins section in the WordPress Admin. Keep this description to fewer than 140 characters.
 * Version:           1.0.0
 * Requires at least: 5.2
 * Requires PHP:      7.2
 * Author:            Your Name
 * Author URI:
 * Text Domain:       plugin-slug
 * License:           GPL v2 or later
 * License URI:
 * Update URI:

Also if you are creating a network plugin, there is an extra parameter Network that if you set it to true it can only be activated at network level.

* Network: True

Add Namespace and Composer Autoload

Why: To avoid naming collision the best way to do this is to use a class. To take this a step further I would like to use Namespace and autoload to make the plugin easier to scale. A great reference on why namespace and autoloading matters is the article Use autoloading and namespacing in PHP.

First we will need to create a folder which will house our root class for the plugin. Our root folder will be Plugin and we will create the Plugin.php to corresponds with the Plugin class.

So we wiil start out with creating the file /wp-content/plugins/player-card/Plugin/Plugin.php and inside of the Plugin.php file we will put the following

namespace Donte\PlayerCardPlugin;

class Plugin {


After creating your new folder with the class you will have to create a composer.json file. To do that run:

composer init

you can hit enter all the way through until you get the Add PSR-4 autoload mapping? Maps namespace “Donte\PlayerCardPlugin” to the entered relative path. [src/, n to skip]: here you can put your new directory name which should be Plugin/

If you see a src directory make sure to check your composer file as you might have forgot to put your Plugin path as your autoload source. You can change this easily by

  1. Removing the src directory.
  2. Navigate to composer.json
  3. Changing "src/" to "Plugin" so that line should end up looking like "Donte\\Playercard\\": "Plugin/"
  4. After saving the file go back to the command line and run composer dump-autoload.

After we have that set up we will now have to call our class from the plugin main file player-card.php.

We can do this one of two ways.

1. We can call the plugin with call it as a new class. First we need to make sure we are calling the composer autoload file as well.

use Donte\PlayerCard\Plugin;

require __DIR__ . '/vendor/autoload.php';

new Plugin;

2. We can use the singleton pattern to initiate the plugin. This will basically ensure that the class will only be called once, and we can avoid any name collison.

The plugin class architecture will have to change to mirror something like this

// General Plugin class.
class Plugin {
  // Hold the class instance.
  private static $instance = null;
  // The constructor is private
  // to prevent initiation with outer code.
  private function __construct()
    // The expensive process (e.g.,db connection) goes here.
  // The object is created from within the class itself
  // only if the class has no instance.
  public static function getInstance()
    if (self::$instance == null)
      self::$instance = new Plugin();
    return self::$instance;

Then we can just call the instance as a static function in the main plugin file


I’m going to leave this section here as this will be a multipart walkthrough for me.





Leave a Reply

Your email address will not be published. Required fields are marked *