Table of contents
- Watch Tutorial
- What you will learn in this video:
- domain-core.php – main plugin file
- Adding code to files in the core directory/folder.
- Init.php – the initialiser class
- Adding code to files in the Base folder.
- Plugin Activation
- ReusableBlock Class
- Explaining the code.
What you will learn in this video:
In this video, you will learn how to create a PSR-4 WordPress Plugin.
You will start by creating the directory structure for your plugin and then move on to creating the basic files required for a functioning plugin.
After that, you will create a custom block and add it to your plugin.
Finally, you will test your plugin and make sure it is working correctly.
Plugin Directory Structure
Using the code editor of your preference, navigate to the Plugins folder and create a new folder domain-core. The domain-core folder will contain all our plugin files.
We will create the following files and folder at the root level of the plugin folder.
- The core directory/folder
- composer.json file
- domain-core.php – the main plugin file.
You need to start with these files at the plugin’s root level directory. We will discuss the folder and file contents in the next topic. First, let’s go into the core directory and add more files and directories we will use in our plugin.
Inside the core folder, we need to create the following;
- Admin folder/directory
- Base folder/directory
- Init.php file
The create the following files inside the Base folder.
In the Admin folder, -we will create the ReusableBlock.php. This is where we will be adding the reusable block functionality for them to appear on the Admin menu.
The plugin Github repo has some files and folders that we have not created in the steps above. We will look at how these are created in the following topics.
Adding code to files in the domain-core directory.
Now that we have set up the file structure. Let us add some code to the files we created in the previous topic.
We will start with the composer.json
Open the composer.json file and paste the following code. This file is located at the root level of our plugin directory, as we saw in the previous topic.
Explaining the code
We use the composer.json file for mainly two things. These are;
- Specify the dependencies of our plugin utilises using the require key. For now, our plugin is not using any third-party components/libraries, so this will be empty.
- Autoloading classes using the autoload field.
We use this field to map our namespace to the directory where all our classes are found. In this tutorial, we will map our namespace Domain_Core to the core folder we created above.
We will use the psr-4 autoloader.
To reference classes inside our plugin, such as ReusableBlock in ResuableBlock.php. We will use Domain_Core\\Admin\\ReusableBlock. This line of code will look up the code via this directory core/Admin/ReusableBlock.php.
To understand this, we have used the namespace Domain_Core to point to the core.
We will further see how the autoloading process works in the later stages of this lesson.
Take note of the naming convention of the namespace. It should start with the capital letter and be separated by the underscore “_” and not a dash “-”
Other fields in composer.json
The composer.json specifies other metadata related to our project. These are;
The name field/property defines the name of the package. It is usually defined by the vendor/project-name. for this package the name is mrkwp/domain-core.
Here the vendor is mrkwp, and the project name is domain-core.
The description field describes the package.
The type fled describes the types of the package. In this case, it is a “project” type. By default, packages are assigned type – “library”. Other types supported by composer include meta package and composer plugin.
License property describes the license of this package. For example, this package is under a GPLv2 license.
Provides details such as the name, email, role and homepage.
We use this field to set another alternative directory for the vendor files. For example, in the code above, we set the vendor fields to be stored in the lib folder.
By default, vendor files are stored in the vendor directory. However, we have observed that our plugins used on sites hosted on WP Engine have issues when these files are stored inside the vendor directory. We, therefore, configure these to be stored in the lib folder.
Read more about the composer.json file in the Basic usage – composer documentation.
domain-core.php – main plugin file
Open the domain-core.php and add the following code.
We use the main plugin file to add details about our plugin in this file using the header comment lines 2 – 3. These details are;
- Plugin Name
- Plugin URI
- Author URI
- Text Domain
- Domain Path
- Version and Package
Read more about the header comment requirements in the WordPress documentation.
After the header comment block, we will add more lines of code to the domain-core.php to execute the following.
- Line of code to prevent direct access to the file on the server – Line 15 and 16.
- Composer loader that will check for the existence of the autoloader and it requires it/ loads it. Lines – 18 – 21.
- The activation hook to run when the plugin is activated. Lines 23 – 31.
- The deactivation hook is to run when the plugin is deactivated. Lines 33- 45.
- Code to check for the Init class and then run the initialisation.
You should take note that on lines 29,39 and 47, we have referenced classes using the following syntax.
Domain_Core\Base\Activate – for the Activate Class
Domain_Core\Base\Deactivate – for the Deactivate Class
Domain_Core\Init – for the init Class
We have not used “core” anywhere because we already mapped it to our namespace Domain_Core in the composer.json.
Adding code to files in the core directory/folder.
Init.php – the initialiser class
Open the Init.php file and add the following code.
Explaining the code.
We start our code by defining our package – Domain-Core
We add the namespace Domain_Core.
You might have noticed that we used first set the namespace to Core_Functions in the video. We later corrected this to Domain_Core.
The Init Class
We create a final class – Init. This class has to be a final because we will never extend this class. It has to be the only class in the core directory. As we will see, this class handles the initialization of all our classes/services.
The Init class has three methods.
These functions/methods do the following.
This class gets the services/classes we will be adding to our plugin. So the ReusableBlocks class inside the Admin directory will be added here, as we will see later in the course.
This class runs a for loop for the services/classes obtained from the get_services method.
First, it instantiates the class and stores it in the service variable (by calling instantiate method)
It, thus, checks for the register method in the instantiated class stored in the service variable.
If it exists, it calls its register method.
At this stage, we have not yet seen the register method. We use this method to register any hooks and filters in our plugin. We will take a look at this later.
This method/function is called inside the register_services function. It simply instantiates a class and returns the instantiated class stored in the service variable. In the service variable, we check for the register method using the register_services method.
Adding code to files in the Base folder.
The Base folder contains 3 classes. These are;
- Activate Class – for the activate method.
- Deactivate Class – for reactive method.
- BaseController Class – for plugin base methods.
We will import the package and namespace lines for these three files from the Init.php file.
Open the Activate.php file and add the following code.
The Activate Class has the activate method, which flushes rewrite rules when the plugin is activated.
Open the Deactivate.php file and add the following code.
The Deactivate Class has the deactivate method, which also flushes rewrite rules when the plugin is activated.
You can call more functions when activating or deactivating the plugin by adding functions inside in their respective activate and deactivate methods.
Open the BaseController.php file and add the following code.
We use the BaseController class to set up a series of base methods. These methods are plugin references for stuff such as the plugin directory path, among others.
Launch the Local site and go to your WP Admin dashboard.
Navigate to plugins and activate the Core Functions Plugin.
We made some corrections during the first activation test in the video tutorial. We changed the version number from 1.0.5 to 1.0.0 because this was the first version of the plugin we had created. Version 1.0.5 doesn’t make sense at this point.
Another error we encountered was the redeclaration of the activate_plugin function. This function name is already declared in the plugin.php core files of WordPress.
We changed function names for the activate and deactivate methods in domain-core.php. This name change avoids conflict with the function names in plugin.php. This is inside the app\public\wp-admin\includes directory.
Thus, we changed the duplicated function names to activate_domain_core and deactivate_domain_core.
You will not encounter these errors when you activate the plugin. We have already fixed the above bugs in the code via GitHub. So, you do not need to make further changes to the code you pulled from the repository.
In the tutorial, you will notice that the plugin is activated, but we have a warning. The warning shows up because the public static function register_services inside Init.php that is meant to register services has no classes to register.
We are yet to add the ReusableBlocks class in the get_services function. This class is passed onto the register_services method where it is then registered. This is what we will cover in the next step of the course.
We need to make changes to the get_services function inside Init.php. It needs to return an array. This array can be empty for now, but we will add the Reusable class after we have created it.
Open the ReusableBlock.php file and add the following code.
Explaining the code.
We will start with the header comment to specify the package that is Domain_Core.
Add the namespace. This time it will be Domain_Core\Admin since we are in the Admin directory. The namespace should always match your folder names.
Create the ReusebaleBlocks class. Inside this class, we will add two functions.
- The register function/method
- The add_resusable_blocks_admin_menu
Let us look at what these two functions will execute.
The register function/method
In this function definition, we will add the admin_menu hook. This hook will invoke the add_reusable_blocks_admin_menu function that we have yet to define.
You recall that the Init class has the register_services function. This checks whether the instantiated classes have the register method, and after that, it invokes it.
For the ReusableBlocks class, this is the register method that gets to be invoked.
To improve on code readability, ensure to document your functions.
Within the ReusableBlocks class ( but outside the register method), define the add_reusable_blocks_admin_menu function. This function displays the reusable blocks via the WP-Admin menu.
In the code gist above, we defined the function from lines 23 – 25.
Read more about this function/snippet from this article: Reusable Blocks accessible in WordPress admin area.
This code snippet will add the reusable block menu to your admin screen.
Register the function inside Init.php
Go to the get_services function inside the Init.php file. Inside the empty array, the function returns, add the function the ReusableBlock class, but we do this using the namespace that is like this Admin\ReusableBlock::class.
Go to the get_services function inside the Init.php file. Go to the empty array that the function returns. Add the ReusableBlock class using the namespace Admin\ReusableBlock::class.
The Reusable Blocks menu item should now be visible on your WP-Admin menu.