WordPress
Article

Developing for the WordPress.org Plugin Directory

By Narayan Prusty

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 WordPress Plugin Directory

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.

  • http://w3guy.com Agbonghama Collins

    Great overview on plugin submission to the official Plugin repository,

    • http://qnimate.com/ Narayan Prusty

      Thanks Agbonghama.

  • http://69plugins.com/ Pradnyankur Nikam

    Hello Narayan Prusty,

    First of all thank you very much for writing useful article. There is a typo under “Activation and Deactivation Files” section. On line number 11 the PHP codes,

    register_deactivation_hook(__FILE__, “plugin_activated”);

    should be

    register_activation_hook(__FILE__, “plugin_activated”);

    As its calling “plugin_activated” function, it should call the function on WordPress’s “register_activation_hook” action hook.

    Thanks for the article again :-)

    • http://qnimate.com/ Narayan Prusty

      Thanks for pointing the mistake. I will correct it.

Recommended

Learn Coding Online
Learn Web Development

Start learning web development and design for free with SitePoint Premium!

Instant Website Review

Use Woorank to analyze and optimize your website to improve your website to improve your ranking!

Run a review to see how your site can improve across 70+ metrics!

Get the latest in WordPress, once a week, for free.