Beginners Guide To Create a WordPress Plugin
Welcome to the "Beginner's Guide to Creating a WordPress Plugin," where we simplify the journey of building your first plugin from scratch. Whether you're a hobbyist or an aspiring developer, this guide will walk you through setting up your plugin's folder and file structure, explaining the importance of a well-defined plugin header, and detailing each step involved in activating and managing your plugin in WordPress. By the end of this guide, you'll have a clear understanding of how to craft a plugin that enhances your website with custom features and functionalities.
If your looking to elevate your site with a custom plugin that does exactly what you need.
Contact us to start your custom plugin project today!

Folder & File Structure
To get started, create a new folder in the WordPress plugin directory:
- Name the folder ‘website-custom-features’.
- Inside this folder, create files named
‘website-custom-features.php’
‘index.php’ - Additionally, create an 'inc' subfolder to house your CSS and JavaScript files:
- Inside the 'inc' folder, add:
- style.css
- script.js

Creating The Plugin Header
Setting up the WordPress Plugin Header involves adding a specially formatted comment block to your main plugin file. This header contains metadata that WordPress uses to identify and manage the plugin within the admin dashboard.
website-custom-features.php
<?php
/**
* Plugin Name: Website Custom Features
* Version: 1.0.0
* Description: A brief description of the plugin's functionality.
* Author: Your Name
* Author URI: https://example.com
* Plugin URI: https://example.com/my-awesome-plugin
* License: GPLv2 or later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
* Text Domain: website-custom-features
* Domain Path: /languages
*/
Metadata Options Explained
Setting up the WordPress Plugin Header involves adding a specially formatted comment block to your main plugin file. This header contains metadata that WordPress uses to identify and manage the plugin within the admin dashboard.Field | Description | Required |
---|---|---|
Plugin Name | The display name of the plugin, shown in the WordPress admin plugins list. | Yes |
Version | The version number of the plugin. Helps track updates and compatibility. | Yes |
Description | A short description of the plugin's functionality, shown in the admin plugin list. | Recommended |
Author | The name of the plugin's author or team. | Recommended |
License | The licensing information for the plugin (e.g., GPLv2 or later). | Recommended |
Text Domain | The unique identifier used for internationalization (i18n) and translations. | Recommended |
Plugin URI | A URL pointing to the plugin's homepage or documentation. | No |
Author URI | A URL pointing to the author's website or profile. | No |
License URI | A URL pointing to the full text of the license. | No |
Domain Path | The folder where translation files are stored, relative to the plugin directory (e.g., /languages). | No |
Requires at least | The minimum WordPress version required to run the plugin. | No |
Requires PHP | The minimum PHP version required to run the plugin. | No |
Update URI | A custom URL for managing plugin updates, used to prevent plugins from conflicting with others on WordPress.org. | No |
Stop Direct Access
The snippet is a common security practice in WordPress development, aimed at preventing unauthorized direct access to PHP files. The code checks if the ABSPATH
constant is defined, indicating access within the WordPress environment. If not, it implies direct and potentially unauthorized access via URL or file path, prompting the exit
function to terminate the script to prevent execution.
website-custom-features.php
// ------------------------------------------------ PREVENT DIRECT ACCESS
// Prevent unauthorized direct access to the file.
if (!defined('ABSPATH')) {
exit;
}
Add CSS & Javascript Files To Your Plugin
In your WordPress plugin, defining constants for the plugin's URL and directory path simplifies accessing resources throughout the plugin. WCFP_PLUGIN_URL is set to the URL of the directory containing the plugin file, which helps in efficiently linking to assets like CSS and JavaScript files. WCFP_PLUGIN_DIR provides the server path to the same directory, facilitating file operations within the plugin. These constants streamline code management by eliminating repetitive function calls and ensuring consistent path usage across the plugin's codebase.website-custom-features.php
// ------------------------------------------------ DEFINE CONSTANTS
// Plugin's public URL
// http://website.com/wp-content/plugins/website-custom-features/
define('WCFP_PLUGIN_URL', plugin_dir_url(__FILE__));
// Directory path for file operations
// C:\xampp\htdocs\website\wp-content\plugins\website-custom-features
define('WCFP_PLUGIN_DIR', plugin_dir_path(__FILE__));
website-custom-features.php
// ------------------------------------------------ ENQUEUE SCRIPTS
/*
Enqueue CSS and JavaScript files for the plugin with versioning
based on file modification times. This prevents having to clear
cache every time there is a new change.
*/
function WCFP_add_scripts() {
$css_file = WCFP_PLUGIN_URL . 'inc/style.css';
$css_file_version = filemtime(WCFP_PLUGIN_DIR . 'inc/style.css');
wp_enqueue_style('WCFP-main-style', $css_file, [], $css_file_version);
// Main JS
$js_file = WCFP_PLUGIN_URL . 'inc/script.js';
$js_file_version = filemtime(WCFP_PLUGIN_DIR . 'inc/script.js');
wp_enqueue_script('WCFP-main-script', $js_file, ['jquery'], $js_file_version, true);
}
add_action('wp_enqueue_scripts', 'WCFP_add_scripts');
The function WCFP_add_scripts() is defined to handle the enqueueing of CSS and JavaScript files.
Versioning: Both CSS and JavaScript files are versioned using filemtime()
, a PHP function that returns the last modified time of the file. This is used here to append a version number to the stylesheet and script URLs. The version number being the last modification timestamp helps in invalidating the browser cache whenever the files are updated so that you don't need to manually clear cache each time you make a change.
wp_enqueue_style(): WordPress function to enqueue the stylesheet. It takes parameters like handle name, source URL, dependencies (none in this case []), version number (based on file modification time), and media type (default is 'all').
wp_enqueue_script(): WordPress function to enqueue scripts. It is similar to wp_enqueue_style() but also includes a parameter for specifying whether the script should be loaded in the footer (true in this case).
Action Hook: The add_action() with the wp_enqueue_scripts hook binds the WCFP_add_scripts() function to WordPress's script and style enqueueing process. This ensures that the plugin's scripts and styles are loaded correctly within the WordPress front-end.
Plugin Activation, Deactivation & Uninstallation Hooks
Managing the lifecycle of a plugin is crucial for maintaining a clean and efficient website environment. This management is primarily handled through the use of Plugin Activation and Deactivation Hooks. These hooks allow developers to execute code at key stages of a plugin's lifecycle—specifically when a plugin is activated, deactivated, or uninstalled.
While not every plugin may require complex setup or cleanup processes, it is considered best practice to implement these hooks. We'll just add them as placeholders for now to our plugin setup template.
They are particularly necessary for plugins that:
- Make persistent changes to the WordPress database (like adding custom tables).
- Register cron jobs or custom post types.
- Add options or modifications to the wp_options table.
website-custom-features.php - Add Activation, Deactivation & Uninstallation Hooks
// ON ACTIVATION
register_activation_hook(__FILE__, 'WCFP_activate');
function WCFP_activate() {
// Additional code here
}
// ON DEACTIVATION
register_deactivation_hook(__FILE__, 'WCFP_deactivate');
function WCFP_deactivate() {
// Additional code here
}
// ON UNINSTALL
function WCFP_uninstall() {
// Additional code here
}
register_uninstall_hook(__FILE__, 'WCFP_uninstall');
Plugin Activation Hook
The activation hook in WordPress is used to perform actions when your plugin is activated. This can include setting up default settings, creating custom database tables, or performing initial setup tasks that are necessary for your plugin to function correctly.
To use an activation hook, you register a function with register_activation_hook()
. This function will be called when your plugin is activated via the WordPress admin panel.
website-custom-features.php
register_activation_hook(__FILE__, 'WCFP_activate');
function WCFP_activate() {
/* EXAMPLE
//-- Set default options --//
add_option('my_plugin_options', 'default_value');
//-- Create custom database tables --//
global $wpdb;
$table_name = $wpdb->prefix . 'my_custom_table';
$sql = "CREATE TABLE $table_name (
id mediumint(9) NOT NULL AUTO_INCREMENT,
time datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
name tinytext NOT NULL,
text text NOT NULL,
url varchar(55) DEFAULT '' NOT NULL,
UNIQUE KEY id (id)
);";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
//-- Other setup tasks --//
// Additional code here
*/
}
Plugin Deactivation Hook
The deactivation hook is used to reverse any actions that shouldn't persist after the plugin is deactivated but not necessarily uninstalled. This might include removing temporary data or stopping cron jobs.
You use the register_deactivation_hook()
to clean up tasks when your plugin is deactivated.
website-custom-features.php
register_deactivation_hook(__FILE__, 'WCFP_deactivate');
function WCFP_deactivate() {
/* EXAMPLE
//-- Remove temporary data --//
delete_transient('my_plugin_temp_data');
//-- Stop cron jobs --//
wp_clear_scheduled_hook('my_plugin_cron_job');
//-- Revert settings temporarily changed by the plugin --//
update_option('my_plugin_settings', 'original_value');
*/
}
Plugin Uninstall Hook
For complete cleanup, including when your plugin is uninstalled, you need to use the uninstall hook. This hook should remove any permanent changes your plugin has made, such as deleting custom tables and options.
To handle uninstallation, you can include an uninstall.php file in your plugin's root directory or use register_uninstall_hook()
. The uninstall.php approach is more robust and is preferred for more extensive cleanup tasks.
website-custom-features.php
function WCFP_uninstall() {
/* EXAMPLE
//-- Delete options --//
delete_option('my_plugin_options');
//-- Drop a custom database table --//
global $wpdb;
$wpdb->query("DROP TABLE IF EXISTS {$wpdb->prefix}my_custom_table");
*/
}
register_uninstall_hook(__FILE__, 'WCFP_uninstall');
Activate The Plugin
In the wordpress sidebar go to plugins and click activate on your new plugin

Check out our FREE ONLINE
WordPress Plugin Development Course