Alexander Sanchez
NicaSource
Published in
12 min readAug 4, 2022

--

How to build a simple but complete WordPress plugin

How to build a simple but complete WordPress plugin

Before building a WordPress plugin or programming anything, we must define our project goal. In this case, the purpose is to show how to create a new WordPress plugin from zero.

What Plugin Features Will We Be Learning?

Our plugin will have the ability to:

  • Be installed
  • Be uninstalled — in this part, we will delete the data
  • Create tables in the database
  • Perform the complete CRUD of the data
  • Create the complete CRUD of the native WordPress tables. Specifically, the wp_posts table since we will make custom post type).

As an example for this NS Insight, I will be teaching you to create a plugin to record a company’s client list. This could easily be used when listing clients on a website, like shown below, displaying sponsors on an event’s website, or just for internal purposes.

Yes, yes, yes, I know there are many plugins out there with the same features. Some existing plugins might even have more features than the ones described above. However, this project aims to demonstrate how to create a plugin from zero.

Theme vs. Plugin

When you have experience developing custom themes in WordPress, you notice that some functions and methods are frequently repeated in the plugin and the theme. Those two have similar results, with the difference being that the functionality gets restricted to the theme and that the plugin is independent.

File Organization

There is no such thing as a unique pattern for organizing the plugin files. Programmers tend to manage them as they wish. I have found that, for me, the best way to organize a project like the one we will be creating is the following:

The first thing we need to do is create a folder and name it after your project. Our plugin code will be inside of it. We will start by creating a .php with the same name as our plugin folder (in this case, clients- ns.php). This file is the minimum functional requirement for a plugin.

Within our plugin, we will need to add a “Heade.” This is a comment in PHP where the plugin and the developer’s data should be found.

These are our header’s fields:

Client- ns.php

/*** Plugin Name: Clients NicaSource* Plugin URI: https://nicasource.com/* Description: This plugin is for managing clients.* Version: 1.0* Requires at least: 5.2* Requires PHP: 7.2* Author: Alexander Sanchez* Author URI: https://nicasource.com/* License: GPL v2 or later* License URI: https://www.gnu.org/licenses/gpl-2.0.html*/

Once we have finished setting up our header, we will be able to see the plugin listed and ready for activation in the “WordPress Plugin Section.” Activating it at this point won’t affect us, but we will revisit later.

Let’s start programming.

Installation hooks

Adopting good practices from the beginning will simplify your life! Let’s define our file through a path and keep it constant so we can access it whenever needed.

Client- ns.php

define ( ‘NS_PATH’ , plugin_dir_path ( __FILE__ ));
define ( ‘NS_FILE’ , __FILE__ );

Now, we will create a folder with our code organized by files according to the tasks performed. This folder will be called “inc.” And we will be ready to make our first hook: the install and uninstall hook.

Inc/install-uninstall.php

<?php//installation and uninstallation hooks wordpressregister_activation_hook ( NS_FILE , ‘clients_ns_install’ );register_deactivation_hook ( NS_FILE , ‘clients_ns_deactivate’ );register_deactivation_hook ( NS_FILE , ‘clients_ns_uninstall’ ); //uninstall hook wordpress (delete all data)function clients_ns_install(){global $wpdb;$table_name = $wpdb -> prefix . ‘clients_ns’ ;$sql = “ CREATE TABLE $table_name (id mediumint( 9 ) NOT NULL AUTO_INCREMENT,yam varchar ( 255 ) NOT NULL ,email varchar ( 255 ) NOT NULL ,country varchar ( 255 ) NOT NULL ,PRIMARY KEY (id)); “ ;require_once ( ABSPATH . ‘wp-admin/includes/upgrade.php’ );dbDelta ($sql);}function clients_ns_uninstall(){global $wpdb;$table_name = $wpdb -> prefix . ‘clients_ns’ ;$wpdb -> query( “DROP TABLE IF EXISTS $table_name “ );}function clients_ns_deactivate(){//nothing}

These functions create a table with fields when we install our plugin. And it will delete the table once we uninstall it.

If you want to double-check that the install action was successful, you can verify that the table was created in the database below.

Create a class for data registration

Then we will create a class called clients with the CRUD methods, following object-oriented programming principles. We will have something like this:

<?php//create class clients with CRUD methodsclass clients {//create a function to insert a new clientpublic function insert_client($name, $email, $country) {global $wpdb;$table_name = $wpdb -> prefix . ‘clients_ns’ ;$wpdb -> insert($table_name, array(‘name’ => $name,‘email’ => $email,country => $country));}//create a function to get all clientspublic function get_clients() {global $wpdb;$table_name = $wpdb -> prefix . ‘clients_ns’ ;$clients = $wpdb -> get_results( “ SELECT * FROM $table_name “ );return $clients;}//create a function to get a client by idpublic function get_client_by_id($id) {global $wpdb;$table_name = $wpdb -> prefix . ‘clients_ns’ ;$client = $wpdb -> get_row( “ SELECT * FROM $table_name WHERE id = $id “ );return $client;}//create a function to update a clientpublic function update_client($id, $name, $email, $country) {global $wpdb;$table_name = $wpdb -> prefix . ‘clients_ns’ ;$wpdb -> update($table_name, array(‘name’ => $name,‘email’ => $email,country => $country), array(go => $id));}//create a function to delete a clientpublic function delete_client($id) {global $wpdb;$table_name = $wpdb -> prefix . ‘clients_ns’ ;$wpdb -> delete($table_name, array(go => $id));}}

In this class, we defined the four methods for a CRUD.

Create a view for the admin

Now, at the root of our project, we will create a folder called “admin” where we will log the views and functionalities of the “WordPress Administration Panel.”

But first, we must create the hook that allows views from the administration panel with the following code:

inc/admin.php

<?php// hooks wordpress for create admin menuadd_action ( ‘admin_menu’ , ‘clients_ns_menu’ );function clients_ns_menu(){add_menu_page (‘NicaSource Clients’ ,‘Clients NS’ ,‘manage_options’ ,‘clients_ns’ ,‘clients_ns_admin_page’ ,‘dashicons-admin-users’ ,6 );}function clients_ns_admin_page(){//include admin fileinclude_once NS_PATH . ‘admin/index.php’ ;}

In the admin/index.php file, we will create the code shown in the admin section and a form to insert new clients. Although we can create our own classes and CSS styles, we will use WordPress ones in this example.

Admin/list- client.php

< div class = “wrap” >< h1 >NicaSource Clients</ h1 >< table class = “wp-list-table widefat fixed striped” >< thead >< tr >< th class = “manage-column” >Name</ th >< th class = “manage-column” >Email</ th >< th class = “manage-column” >Country</ th >< th class = “manage-column” >Actions</ th ></ tr ></ thead >< tbody ><?php//get all clients$clients = new clients();$clients = $clients -> get_clients();//loop clientsforeach ($clients as $client) {?>< tr >< td > <?php echo $client -> name; ?> </ td >< td > <?php echo $client -> email; ?> </ td >< td > <?php echo $client -> country; ?> </ td >< td >< to href = “ <?php echo admin_url ( ‘admin.php?page=clients_ns&action=edit&id=’ . $client- > id); ?> “ >Edit</ a >< to href = “ <?php echo admin_url ( ‘admin.php?page=clients_ns&action=delete&id=’ . $client- > id); ?> “ >Delete</ a ></ td ></ tr ><?php}?></ tbody ></ table >< h2 >Add New Client</ h2 >< form action = “ <?php echo admin_url ( ‘admin.php?page=clients_ns&action=add’ ); ?> “ method = “post” >< table class = “form-table” >< tr >< th scope = “row” >< label for = “name” >Name</ label ></ th >< td >< input type = “text” name = “name” id = “name” class = “regular-text” ></ td ></ tr >< tr >< th scope = “row” >< label for = “email” >Email</ label ></ th >< td >< input type = “text” name = “email” id = “email” class = “regular-text” ></ td ></ tr >< tr >< th scope = “row” >< label for = “country” >Country</ label ></ th >< td >< input type = “text” name = “country” id = “country” class = “regular-text” ></ td ></ tr ></ table >< p class = “submit” >< input type = “submit” name = “submit” id = “submit” class = “button button-primary” value = “Add Client” ></ p ></ form ></ div ><?php

We will start by instantiating our client class and applying the “get_all” method to extract all the database records. After that, we will create a form where we have the inputs to register a new client, and we will have a view like the one below:

In the Add New Client form, when we click on the “Add Client” button, it will send us the ‘POST’ data to the same URL but with a variable called to action and with value add, which we have to validate to capture the data and register it in the database.

Now, we will introduce a switch case to capture all the requests made to write a slightly more dynamic code. We will also show a code as required, as follows:

<?php//create UI for list clients and add new client in html fileif ( isset ($_GET[ ‘action’ ])){switch ($_GET[ ‘action’ ]){case ‘add’ :include_once NS_PATH . ‘admin/add-client.php’ ;include_once NS_PATH . ‘admin/list-clients.php’ ;break ;case ‘delete’ :$client = newClients ();$client -> delete_client($_GET[ ‘id’ ]);include_once NS_PATH . ‘admin/list-clients.php’ ;break ;case ‘edit’ :$client = newClients ();$clietToedit = $client -> get_client_by_id($_GET[ ‘id’ ]);include_once NS_PATH . ‘admin/list-clients.php’ ;break ;case ‘update’ : //update client$client = newClients ();$client -> update_client($_GET[ ‘id’ ], $_POST[ ‘name’ ], $_POST[ ‘email’ ], $_POST[ ‘country’ ]);include_once NS_PATH . ‘admin/list-clients.php’ ;break ;default :$client = newClients ();$clients = $client -> get_clients();include_once NS_PATH . ‘admin/list-clients.php’ ;break ;}} else {include_once NS_PATH . ‘admin/list-clients.php’ ;}?><?php

To add a client, we have to call the add-clien.php file. That file is where the script to register a client is located. After that’s done, we will be able to show the list.

Admin/add-client.php

//register client on databaseif ( isset ($_POST[ ‘name’ ]) && isset ($_POST[ ‘email’ ]) && isset ($_POST[ ‘country’ ])) {$name = $_POST[ ‘name’ ];$email = $_POST[ ‘email’ ];$country = $_POST[ ‘country’ ];$client = newClients ();$client -> insert_client($name, $email, $country);}

Now, we are ready to register the new client in the form.

And when we click the “Add client” button, the client will be saved correctly.

Are you sure you want to delete this client?

To continue with our CRUD, we will ask the user to confirm if they want to delete that record. We can Javascript may for this purpose:

When this process is completed, we see that the “Delete” button redirects to itself but also sends two variables’ actions and the id with their respective value.

$client = newClients ();

$client -> delete_client($_GET[ ‘id’ ]);

Expects the id and call the delete_client method we created in the class.

It’s time to update a client!

Updating a record is essential, and we want to give our users the ability to do so. If a user clicks on the “Edit” button, they should see a form with the data to be edited.

Below you will find the code we will use to accomplish this task. If we take a look at the switch case, we will notice that a request is made, and it is saved in a variable called $clientToedit which is an object with the client’s data to be edited:

<?phpif ( isset ($clietToedit) && $clietToedit != null ){$client = $clietToedit;?>< h2 >Edit Client</ h2 >< form action = “ <?php echo admin_url ( ‘admin.php?page=clients_ns&action=update&id=’ . $client -> id); ?> “ method = “post” >< table class = “form-table” >< tr >< th scope = “row” >< label for = “name” >Name</ label ></ th >< td >< input type = “text” name = “name” id = “name” class = “regular-text” value = “ <?php echo $client -> name; ?> “ ></ td ></ tr >< tr >< th scope = “row” >< label for = “email” >Email</ label ></ th >< td >< input type = “text” name = “email” id = “email” class = “regular-text” value = “ <?php echo $client -> email; ?> “ ></ td ></ tr >< tr >< th scope = “row” >< label for = “country” >Country</ label ></ th >< td >< input type = “text” name = “country” id = “country” class = “regular-text” value = “ <?php echo $client -> country; ?> “ ></ td ></ tr ></ table >< p class = “submit” >< input type = “submit” name = “submit” id = “submit” class = “button button-primary” value = “Edit Client” ></ p ><?php}

As a result, the data will be loaded in the input when you click on button “Edit”

We can now modify the data and send the updated information to the function. The function below will update the data on the database.

$client = newClients ();

$client -> update_client($_GET[ ‘id’ ], $_POST[ ‘name’ ], $_POST[ ‘email’ ], $_POST[ ‘country’ ]);

Eureka!

We are ready to register, read, edit and delete the records. It is time to display the data on the website. We will do it with a “Shortcode,” which allows us to print a list of clients on the screen. We will create a file called shortcode.php in the inc folder and include it in clients-ns.php in our main file. The code with the shortcode will be something like this:

<?php//create shortcode for clientsadd_shortcode ( ‘clients_ns’ , ‘clients_ns_shortcode’ );function clients_ns_shortcode(){//generate html for list clients$client = newClients ();$clients = $client -> get_clients();$html = ‘<div class=”clients-ns”>’ ;$html .= ‘<h2>NicaSource Clients</h2>’ ;//generate html table for list clients$html .= ‘<table class=”table table-striped”>’ ;$html .= ‘<thead>’ ;$html .= ‘<tr>’ ;$html .= ‘<th>Name</th>’ ;$html .= ‘<th>Email</th>’ ;$html .= ‘<th>Country</th>’ ;$html .= ‘</tr>’ ;$html .= ‘</thead>’ ;$html .= ‘<tbody>’ ;//loop clientsforeach ($clients as $client) {$html .= ‘<tr>’ ;$html .= ‘<td>’ . $client -> name . ‘</td>’ ;$html .= ‘<td>’ . $client -> email . ‘</td>’ ;$html .= ‘<td>’ . $client -> country . ‘</td>’ ;$html .= ‘</tr>’ ;}$html .= ‘</tbody>’ ;$html .= ‘</table>’ ;$html .= ‘</div>’ ;return $html;}

With that shortcut, we can put our “clients_ns” section anywhere on our site, and it will display a client list table like the one below.

We finally have our project completed. It is a simple project, but it taught us everything it takes to create a WordPress plugin. The key is to follow the order of steps. You can also check the complete project in a .zip file if you need it.

Thanks for checking this out, and see you soon!

--

--