Macbook Pro Showing Text

WordPress is a very popular CMS, and a huge part of its popularity is due to its ability to be extended. It provides a mechanism for developers to write pieces of code that extend its core functionality. Those pieces of code are called plugins. In this article, we will begin to explore the essentials of plugin development.

Plugin location and header

WordPress discovers installed plugins by scanning wp-content/plugins and its first-level subfolders for PHP files with a special header. The header is a comment block containing at minimum a Plugin Name field. A minimal plugin header would be the following:

/*
Plugin Name: Tutorial
*/
PHP

Other possible fields include:

  • Description: A description for the user to understand what the plugin does
  • Version: The plugin’s version
  • Plugin URI: A URI where more information about the plugin can be found
  • License: The license under which the plugin is released
  • License URI: A URI where one can find more information about the license
  • Author: The plugin’s author
  • Author URI: A URI leading to more information about the author
  • Requires at least: The minimum WordPress version the plugin requires to execute
  • Requires PHP: The minimum PHP version the plugin requires to execute
  • Requires Plugins: Other plugins that this plugin depends on
  • Text Domain: the string used for the textdomain for translations
  • Domain Path: a path that contains translations
  • Update URI: for plugins not hosted at the plugin repository, to avoid accidental updates
  • Network: true if the plugin can only be activated network-wide. If not, it should be omitted

As mentioned above, WordPress searches not only wp-content/plugins, but also its direct subfolders. That is because a plugin could include more than one PHP file. In fact, in most cases a plugin comes packed with several source files and a handful of other assets, such as media, stylesheets or client scripts. Therefore it is essential for the author to be able to contain all those files in a plugin subfolder.

Plugin execution

WordPress keeps the enabled plugins list in the database. Before it delivers any content to the client, it executes all enabled plugin files. For example, consider the following code:

<?php
/*
Plugin Name: Tutorial
*/

error_log("Hello plugin");
PHP

Provided that we have activated our plugin, we will notice that a Hello plugin phrase ends up in our debug log for every request. However, we rarely want any code to run unconditionally. In most cases, we want to hook our functionality on actions and filters. For example, the following plugin will wrap any sticky post’s content in a div.sticky element:

<?php
/*
Plugin Name: Tutorial
*/

function tutorial_content_filter($content){
	if(is_sticky()) return "<div class='sticky'>$content</div>";
	return $content;
}

add_filter('the_content','tutorial_content_filter');
PHP

Activation, deactivation and uninstall

Three of the most essential procedures in plugin development are activation, deactivation and uninstall. There are many scenarios in which we want to run some initialization code when the plugin activates, do the opposite when it deactivates and clean up the database/filesystem when it is uninstalled. WordPress provides three register_{action}_hook($file,$function) functions for those scenarios, with {action} being one of activation, deactivation and uninstall respectively:

<?php
/*
Plugin Name: Tutorial
*/

function tutorial_activate(){
  // activation code here
}

function tutorial_deactivate(){
  // deactivation code here
}

function tutorial_uninstall(){
  // uninstall code here
}

register_activation_hook(__FILE__,'tutorial_activate');
register_activation_hook(__FILE__,'tutorial_deactivate');
register_activation_hook(__FILE__,'tutorial_uninstall');
PHP

The $file parameter implies that the corresponding functions may reside in a different file. If not, like the example above, this parameter should be __FILE__.

Now, for the uninstall case specifically, we have a second option. We can include the relevant code in a special uninstall.php file in the plugin’s folder. When WordPress tries to delete the plugin, it will first search for that special file and execute the code in it.