Developing for the WordPress.org Plugin Directory
The official WordPress.org Plugin Directory is home to an amazing collection of useful plugins, it’s usually the first place WordPress users look when seeking to extend the functionality of their sites. The Plugin Directory offers great opportunities for developers, however there are some guidelines you need to follow. A base plugin will help you to easily and quickly get started in the development process.

The Official WordPress.org Plugin Directory
Base Plugin Directories and Files
These are the necessary files and directories for every plugin that you want to publish to the WordPress plugin directory. These files and directories represent your base plugin. The current plugin version and all future releases will be packed into one single directory i.e. plugin-name
.
--plugin-name --assets -screenshot-n.png -icon-256x256.png -banner-772x250.png --trunk --admin --css --js --inc -admin.php --public --css --js --inc -public.php --inc -activation.php -deactivation.php --languages -plugin-name.pot -plugin-name.php -uninstall.php -README.txt --tags
Let’s now review the use of each of these directories and files. We’ll also look at the code we need to put inside the files.
Assets Directory
This directory contains images of the plugin i.e. plugin screenshots, banner image for the plugin page on WordPress.org and an icon.
You can provide any number of screenshots. The screenshots can be any of following formats: png, jpg, jpeg or gif. The screenshot must also show the latest release of your plugin. Suppose you have five screenshots, then your assets directory should look like this:
--assets -screenshot-1.png -screenshot-2.png -screenshot-3.png -screenshot-4.png -screenshot-5.png -icon-256x256.png -banner-772x250.png
Icons must be 256×256 pixels and a banner must be 772×250 pixels. It’s not compulsory to provide screenshots, an icon or a banner, however, providing them is recommended since it does increase engagement with your plugin.
Trunk and Tags Directory
Trunk is your working directory. Here is you’ll write your code. When you want to publish your plugin you’ll need to copy the contents from the trunk directory to a new version directory within the tags directory. The version directory represents the current version of the plugin code.
When you’ve finished creating your new plugin, you’ll want publish it with a version 1.0. Then your directories will look like this:
--plugin-name --assets -screenshot-n.png -icon-256x256.png -banner-772x250.png --trunk --admin --css --js --inc -admin.php --public --css --js --inc -public.php --inc -activation.php -deactivation.php --languages -plugin-name.pot -plugin-name.php -uninstall.php -README.txt --tags --1.0 --admin --css --js --inc -admin.php --public --css --js --inc -public.php --inc -activation.php -deactivation.php --languages -plugin-name.pot -plugin-name.php -uninstall.php -README.txt
The tags/1.0
directory will contain all of the same code as what’s in the current trunk directory.
Now, if you want to modify trunk and release a new version of your plugin as 2.0, then create a new directory tags/2.0
and copy all of the latest code from the trunk directory to this new directory. Therefore your trunk directory should always reflect the current changes. Now your directories would look something like this:
--plugin-name --assets -screenshot-n.png -icon-256x256.png -banner-772x250.png --trunk --admin --css --js --inc -admin.php --public --css --js --inc -public.php --inc -activation.php -deactivation.php --languages -plugin-name.pot -plugin-name.php -uninstall.php -README.txt --tags --1.0 --admin --css --js --inc -admin.php --public --css --js --inc -public.php --inc -activation.php -deactivation.php --languages -plugin-name.pot -plugin-name.php -uninstall.php -README.txt --2.0 --admin --css --js --inc -admin.php --public --css --js --inc -public.php --inc -activation.php -deactivation.php --languages -plugin-name.pot -plugin-name.php -uninstall.php -README.txt
Users download the content inside the version directories, not the trunk directory.
README.txt File
The README.txt file is the primary source of information displayed for the plugin in the WordPress.org plugins directory. It should be present and should clearly explain how to use the plugin and what the plugin does, even if you think it’s obvious.
A README.txt file is present in the trunk directory and also in the version directories of tags directory.
This is sample content of README.txt file for our base plugin. This file is written in markdown.
=== Plugin Name === Contributors: (this should be a comma separated list of wordpress.org userid's of this plugin developers) Donate link: http://example.com/ Tags: tag1, tag2, tag3 Requires at least: 3.0.1 Tested up to: 3.4 Stable tag: 2.0 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html Here is a short description of the plugin. This should be no more than 150 characters. No markup here. == Description == This is the long description. No limit, and you can use Markdown (as well as in the following sections). == Installation == This section describes how to install the plugin and get it working. == Frequently Asked Questions == = This is question 1 = This is answer to question 1 = This is question 2 = This is answer to question 2 == Screenshots == 1. This is description for our first screenshot i.e., screenshot-1.png. 2. This is description for our second screenshot i.e., screenshot-2.png. 3. This is description for our third screenshot i.e., screenshot-3.png. 4. This is description for our fourth screenshot i.e., screenshot-4.png. 5. This is description for our fifth screenshot i.e., screenshot-5.png. == Changelog == = 3.0 = * A change since the previous version. * Another change. = 2.0 = * A change since the previous version. * Another change. == Upgrade Notice == = 3.0 = Upgrade notices describe the reason a user should upgrade. No more than 300 characters. = 2.0 = This version fixes a security related bug. Upgrade immediately.
Most things in the README.txt file are self explanatory.
One of the things you do need to understand is the Stable tag:
. The Stable tag of README.txt file of the trunk directory should point to the name of the latest version directory. This is how the WordPress plugin directory knows the latest and most stable release of the plugin. When you create a new version of your plugin you need to change trunk directory’s README.txt file’s Stable tag value to the new version directory. The Stable tag of README.txt file in the tags version directories should point to the name of that particular version directory.
The README.txt file in the version directories represent each of the versions, and README.txt in the trunk directory represents the latest version release and therefore is same as the current release version directory’s README.txt file.
plugin-name.pot File
Not everyone that uses WordPress speaks English. Therefore you don’t want to prevent non-English speaking users from using your plugin. You can avoid this by translating all your plugin’s displayed strings to different languages.The process of making your plugin compatible for multiple languages is called as Internationalization (i18n). A .pot file contains alternative language versions of your plugin’s strings. Generating a .pot file for your plugin is called Localization (L10n). At SitePoint we’ve covered i18n and L10n in WordPress, something definitely worth checking out if you’re interested.
This language file (.pot) is not loaded automatically, you need to load it using the load_plugin_textdomain
function. To do this, place this code in your plugin’s main file i.e. plugin-name.php file.
load_plugin_textdomain("plugin-name", false, basename(dirname(_FILE_)), "/languages");
Activation and Deactivation Files
inc/activation.php
and inc/deactivation.php
files contain code that is executed when the plugin is activated or deactivated respectively.
Now we need to load inc/activation.php
and inc/deactivation.php
files only during plugin activation and deactivation respectively. We can do this by placing the below code in plugin-name.php
file.
function plugin_activated()
{
require_once "inc/activation.php";
}
function plugin_deactivated()
{
require_once "inc/deactivation.php";
}
register_activation_hook(__FILE__, "plugin_activated");
register_deactivation_hook(__FILE__, "plugin_deactivated");
You can learn more about activation and deactivation hooks here.
uninstall.php
This file is executed when a plugin is deleted by the user. Put this content inside the uninstall.php file
//this check makes sure that this file is not called manually.
if (!defined("WP_UNINSTALL_PLUGIN"))
exit();
//put plugin uninstall code here
Admin and Public Directories
Inside admin/admin.php
is where you’re supposed to put the admin panel dashboard specific functionality of the plugin. Then, inside public/public.php
, is where you’re supposed to put the public facing functionality of the plugin.
Publishing Your Plugin
Your whole plugin is actually a SVN repository on the WordPress.org plugin directory cloud. Once you submit your plugin and it’s approved, you will have a SVN repository on the cloud to which you can make changes or add new version releases.
To make changes or add releases to the remote repository you need to create a local copy of the repository using SVN. Then, make changes to the local copy and then commit it to the remote repository using SVN.
Further Reading
You can refer to WordPress.org plugin directory’s FAQ for your common questions. You can use README.txt validator to validate your README.txt file. You can also generate a README.txt file using the Plugin Readme Generator at GenerateWP.