arrow_back
Back

WordPress plugin development: file structure, headers, and activation

Andrew Dorokhov Andrew Dorokhov schedule 2 min read
menu_book Table of Contents

File structure

It should be either one PHP file inside the plugins directory or a folder that contains PHP files.

Example:

/wp-content/plugins/example-plugin/example-plugin.php

Comment header

Minimal header:

/**
 * Plugin Name: YOUR PLUGIN NAME
 */

Recommended header:

/**
 * Plugin Name:       My Basics Plugin
 * Plugin URI:        https://example.com/plugins/the-basics/
 * Description:       Handle the basics with this plugin.
 * Version:           1.10.3
 * Requires at least: 5.2
 * Requires PHP:      7.2
 * Author:            John Smith
 * Author URI:        https://author.example.com/
 * License:           GPL v2 or later
 * License URI:       https://www.gnu.org/licenses/gpl-2.0.html
 * Update URI:        https://example.com/my-plugin/
 * Text Domain:       my-basics-plugin
 * Domain Path:       /languages
 */

PHPDoc DocBlock:

/**
 * 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:        https://example.com/plugin-name
 * Description:       Description of the plugin.
 * Version:           1.0.0
 * Requires at least: 5.2
 * Requires PHP:      7.2
 * Author:            Your Name
 * Author URI:        https://example.com
 * Text Domain:       plugin-slug
 * License:           GPL v2 or later
 * License URI:       http://www.gnu.org/licenses/gpl-2.0.txt
 * Update URI:        https://example.com/my-plugin/
 */

Here’s a list of all the header fields: open_in_new header fields .

Only one file in the plugin’s folder should have the header comment — if the plugin has multiple PHP files, only one of those files should have the header comment.

Avoiding function name collisions

The first solution is to prefix every function in your plugin with a unique string:

function my_plugin_publish_post_action() {
    // ...
}

add_action('publish_post', 'my_plugin_publish_post_action');

The second solution is to enclose your plugin functions in a class and call the class methods statically.

class MyPlugin {
    public static function publish_post_action() {
        // ...
    }
}

add_action('publish_post', ['MyPlugin', 'publish_post_action']);

Security

if ( ! defined( 'ABSPATH' ) ) {
    exit; // Exit if accessed directly
}

Activation

If you are wondering how a plugin is activated, the explanation is simple: plugin code is executed after the “Activate” button is clicked, then the activation hook is executed.

Plugin API

Filter functions:

has_filter()
add_filter()
apply_filters()
apply_filters_ref_array()
current_filter()
remove_filter()
remove_all_filters()
doing_filter()

Action functions:

has_action()
add_action()
do_action()
do_action_ref_array()
did_action()
remove_action()
remove_all_actions()
doing_action()

Activation / deactivation / uninstall functions:

register_activation_hook()
register_deactivation_hook()
register_uninstall_hook()

Plugin structure

I guess a good starting point is to use the open_in_new WordPress Plugin Boilerplate .

There’s a generator for this: open_in_new https://wppb.me

Packing a plugin into a zip file

zip -r pugin-name-v1.0.0.zip plugin-folder-name
code

Need Help with Development?

Happy to help — reach out via the contacts or go straight to my Upwork profile.

work View Upwork Profile arrow_forward
Next Article

WordPress admin menus: add_menu_page, submenus, and capabilities

arrow_forward