How to create a custom WordPress plugin from scratch


During the past week I was thinking about a new tutorial on how to create a custom WordPress plugin from scratch. The task is not that hard to be done, especially when you have a good idea how WordPress works and what is its files structure.

The following will be a detailed tutorial for custom WordPress plugin creation. I will provide step by step instructions on how to start developing a simple plugin. For better understanding I will add a little piece of code that will query the database and generate backups.

Custom wordpress plugin installation

Let’s start from the point that you have default WordPress installation. What you have to is login to its admin panel and navigate to plugins page. If no new plugin are installed so  far you would see the following on your screen:

WordPress plugins page

WordPress plugins page

These are the plugins that come by default. At this point you are on plugins page and this is the place where our plugin will appear soon. Here is what to do next:

Using FTP client you should access the root folder of your WordPress instance and then open wp-content folder. Inside it you will see plugins folder, open it and create new one named dbmechanic. The name can be of course changed. If you refresh plugin page you will see no change. This is because we create the folder of our plugin, but there is no code to trigger WordPress hooks.

Custom plugin development

As a next step, we have to create a new file that will contain the code of our future plugin. The file name could be dbmechanic.php.

Again WordPress plugin page does not show any signs about a new plugin because we have a folder and main file, but there is no code. So now we have to open dbmechanic.php and add the following header to it:

<?php
/*
Plugin Name: Simple database mechanic
Plugin URI: https://wppotion.com/
Description: A simple database mechanic plugin
Version: 1.0
Author: Leonid G.
Author URI: https://wppotion.com/
License: GPL
*/
?>

 

Now go back to plugins page and refresh it. If everything is fine, you will see our custom plugin in the list.

Custom WordPress plugin

Custom WordPress plugin

As you can see the information from the headers corresponds correctly with WordPress hooks and the name, version, URI and author are displayed as expected on the page.

We have now the basic file and we can proceed and add some options to it. As adding the code piece by piece may break it and generate fatal errors I will paste the entire code and then explain the lines:

<?php
/*
Plugin Name: Simple database mechanic
Plugin URI: http:// wppotion.com/
Description: A simple database mechanic plugin
Version: 1.0
Author: Leonid G.
Author URI: https://wppotion.com/
License: GPL
*/
add_action('admin_menu', 'dbmechanic_admin_actions');
/*
Here we use admin_menu hook and a functions that contains instructions to add a submenu to the general Settings page
*/
function dbmechanic_admin_actions()
{
add_options_page('DBmechanic', 'DB-mechanic', 'manage_options','__FILE__', 'mechanic_admin');
}
/*
As you can see add_options_page takes 5 arguments which define the title of the page, the name of the submenu, 'manage_options' defines who can control the submenu, the next one is the menu slug, mechanic_admin is the function that will display the plugin page.
*/
function mechanic_admin ()
{
/*
Now we will develop the function itself. As you can see there is no closing tag, because we will put some PHP and HTML inside it and the closing tag will be placed in the end.
*/
?>
<!--
Here we close PHP Tag, because what comes next is pure HTML code which should not be messed up with PHP
-->
<div class="wrap">
<h4> Database details: </h4>
<?php
echo "Database ";
echo "&nbsp; &nbsp; &nbsp;".DB_NAME;
echo "<br />";
echo "Mysql user ";
echo "&nbsp;".DB_USER;
echo "<br />";
echo "Password";
echo "&nbsp; &nbsp; &nbsp;".DB_PASSWORD;
echo "<br />";
echo "Hostname";
echo "&nbsp; &nbsp; &nbsp;".DB_HOST;
?>
<!--
Using a little PHP snippet we extract WordPress Mysql details. We do this just to show how the code interacts with wpdb object.
-->
<hr />
<form action="" method="POST" >
<input type="submit" name="database_check" value="Database Check" class="button-primary" />
</form>
<!--
This is form button that works using POST. We also use class that is defined by WordPress as button-primary
-->
<?php
global $wpdb;
if(isset($_POST['database_check']))
{
$AllRecordsCheck = $wpdb->query(
"
SELECT *
FROM $wpdb->options;
"
);
echo "<hr />";
echo 'All records in options table - '.$wpdb->num_rows ;
echo "<hr />";
/*
This code queries wpdb object and extracts and counts the number of rows in options table
*/
$TrRecordsCheck = $wpdb->query(
"
SELECT *
FROM $wpdb->options
WHERE option_name LIKE '\_transient\_feed\_%'
OR option_name LIKE '\_transient\_timeout\_feed\_%'
OR option_name LIKE '\_site\_transient\_timeout\_browser\_%'
OR option_name LIKE '\_transient\_dash\_%'
OR option_name LIKE '\_site\_transient\_browser\_%'
"
);
echo 'Transient rows ( not needed ) - '.$wpdb->num_rows;
/*
Here we extract the rows that contains transient or its variations in the names
*/
echo "<hr />";
$reduction = ($TrRecordsCheck / $AllRecordsCheck )*100;
$rounded = round($reduction, 2);
echo "Possible reduction - approximately <b>$rounded %</b>";
}
/*
Here we calculate the possible reduction and print the percentage.
*/
echo "<hr />";
?>
<form action="" method="POST" >
<input type="submit" name="database_backup" value="Database Backup" class="button-primary" />
</form>
<?php
$dir = plugin_dir_path( __FILE__ );
$url = plugin_dir_url( __FILE__ );
if(isset($_POST['database_backup']))
{
$backupFile = "$dir/backup_db/".DB_NAME."-".date("Y-m-d-H-i-s").".sql.gz";
$exp = "mysqldump --opt -u ".DB_USER." -p'".DB_PASSWORD."' -h ".DB_HOST."  ".DB_NAME." | gzip -9 -c > $backupFile";
system($exp);
echo " </br >Backup generated</br >";
echo "</br >Phisical location of the file <b>$backupFile</b></br >";
}
?>
<!--
This portion here generates a backup button and give instructions on how and where the backup to be generated and kept.
-->
<hr />
<form action="" method="POST" >
<input type="submit" name="database_optimize" value="Database Optimize" class="button-primary" />
</form>
<?php
if(isset($_POST['database_optimize']))
{
$TrRecordsDrop = $wpdb->query(
"
DELETE
FROM $wpdb->options
WHERE option_name LIKE '_transient_feed_%'
OR option_name LIKE '\_transient\_timeout\_feed\_%'
OR option_name LIKE '\_site\_transient\_timeout\_browser\_%'
OR option_name LIKE '\_transient\_dash\_%'
OR option_name LIKE '\_site\_transient\_browser\_%'
"
);
echo "<br />Optimization - done<br />";
}
?>
<!--
Here we perform the optimization itself
-->
<hr />
<form action="" method="POST" >
<input type="submit" name="database_manage" value="Manage Backups" class="button-primary" />
</form>
<?php
if(isset($_POST['database_manage']))
{
?>
<table class="widefat">
<thead>
<tr>
<th>List of the available backups</th>
</tr>
</thead>
<tfoot>
<tr>
<th>
<?php
echo "
<script src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js\"></script>
<script type=\"text/javascript\">
function deleteBackup(backupfile){
$.get( \"".$url."delete.php?delete=\"+backupfile, function( data ) {
//    $( \".result\" ).html( data );
var removedDiv = document.getElementById(backupfile);
removedDiv.parentNode.removeChild(removedDiv);
});
}
</script>
";
$path = "$dir/backup_db";
$dh = opendir($path);
$i=1;
while (($file = readdir($dh)) !== false) {
if($file != "." && $file != "..") {
echo "<div id='$file'>$i. <a href='".$url."backup_db/$file' title='Click to Download'>$file</a> | <a href='#' onclick=\"javascript: deleteBackup('$file')\">Delete Backup</a><br /></div>\n";
$i++;
}
}
closedir($dh);
?>
</th>
</tr>
</tfoot>
<tbody>
</tbody>
<!--
Here we give the option to control the available backups.
-->
<?php
}
?>
<?php
}
?>

Now if everything is fine, you have created your first custom WordPress plugin. Just refresh the plugin page and you will see the following on your screen:

Simple WordPress plugin

Simple WordPress plugin

Summary
Custom wordpress plugin installation and development - how to
Article Name
Custom wordpress plugin installation and development - how to
Description
Custom wordpress plugin installation and development - hooks, functions and comments
Author
Publisher Name
wppotion


Do you want to share your opinion?

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


*

We are not industry specific. We are WordPress specific. We work with everyone to help them find solutions with their troubles.
If you show us the problem you are experiencing, we will show you how to fix it. It is that simple.


Reported WordPress issues

  1. Wordpress Rest API showing theme custom fields within the end point url are refusing to update via a post command
  2. Generate new post WordPress based on MySQL database
  3. Iframe (ads) is blur in Chrome when it is resized to fit in sidebar div
  4. How to make a WordPress page mobile responsive?
  5. Permalink Settings You should update your web.config now [on hold]
  6. how to upload image to wordpress with flutter using REST API
  7. Setting CSS property - filter: blur(x) with JS for site-inner class within genesis framework; Cannot read property 'getAttribute' of null
  8. Error on wordpress on my VPS: Your PHP installation appears to be missing the MySQL extension which is required by WordPress [on hold]
  9. Netlify deploy with results of TypeError: Cannot read property 'replace' of undefined
  10. How to position text at the same vertical level across columns

WordPress problems we are working on

  1. How to target a specific group on Buddypress (WordPress) to show it on a widget?
  2. Is it possible for Month names to be shown in my language
  3. Displaying and grouping posts
  4. Wordpress custom endpoints (WP_REST_Controller) 404 only on mobile
  5. Set default value in database [on hold]
  6. How do I programmatically set a user as spam in BuddyPress?
  7. Can i edit styling of form in ultimate member wordpress plugin?
  8. wordpress product attribute not creating automatically only work size and color other attributes not work need to add manually again same attribute
  9. Uncaught Error: Syntax error, unrecognized expression on WordPress website
  10. Wordpress website hacked and .htaccess file is creating automatically with strange code

Resolved issues

  1. Wordpress gutenberg editor gallery first image missing [on hold]
  2. how to fix the error No Input file specified on wordpress when using .php extention on pages
  3. How do I integrate Chargebee api to wordpress?
  4. Sorting a wp_query with more than one 'orderby'?
  5. Wordpress API: Sort posts by sticky and date
  6. Column background color not showing up
  7. How to show a row for each column?
  8. Wordpress site's frontend css styles not loading [on hold]
  9. Get the just added term_id (WordPress)
  10. Permalink structure does not get updated
wppotion - powered by persistence and passion