Directory Structure

WordPress plugins are unbelievably versatile and easy to write. Whether your using a mulit-site instalation or just a normal blog there are only a few small rules that you need to obey.

You can either place your plugin as one single file in /wp-content/plugins/ or, if your plugin is going to have a number of files then place them in /wp-content/plugins/my-plugin-dir. As we are going to be using more than one file for our plugin we are going to use the 2nd option.

Now to think of a good plugin to use for this tutorial. It will have to need shortcodes, ajax and have different admin menus for a user’s blog and for the network admin. It is easy to forget that your plugin will be running along any number of plugins on any number of installations. In order to avoid conflict with other plugins the use of classes is highly recommended. The only time you shouldn’t use classes is if your plugin is only a few lines of code.

For those that haven’t used classes before, they can seem daunting at first, but have no fear like everything in programming – once the penny drops you’ll wonder how you couldn’t understand it in the first place. For a basic, very very quick, lesson on objects and classes – A class is a definition of a function that has functions inside it. The object is the variable that this class is assigned to. The functions inside this ‘main’ function (class) are called methods. I will get bombarded by loads of people telling me that I shouldn’t use this analogy, but like I say this is not a lesson on classes.

As our plugin is going to be installed independent of the theme, we need to keep all our files in the one place – our plugin directory:

/wp-content/plugins/my-massive-plugin/

We are going to have html, js, css, images, admin pages, network admin pages and classes. So here is the directory structure:

/wp-content/plugins/
		|
		|---/my-plugin-dir/
				|
				|---/application/
				|		|
				|		|---/includes/
				|		|---/modules/
				|---/public_html/
						|
						|---/css/
						|---/images/
						|---/js/

So an explanation of each:

/wp-content/plugins/my-plugin-dir/

In here you only need your index.php file. This will have the tags for wordpress to know what your plugin does, it will construct your objects, register hooks, init calls, admin pages etc.

/wp-content/plugins/my-plugin-dir/application/

This is where you will be putting your main plugin class.

/wp-content/plugins/my-plugin-dir/application/includes/

Initially I was placing javascript 3rd parties in /public_html/js and php 3rd parties in /application/includes/ but it started to become messy. Some 3rd parties you may use will have both js and php, and when you come back to it later it can be a headache. So ALL 3rd party stuff you may use, like jquery plugins, php classes etc will go here

/wp-content/plugins/my-plugin-dir/application/modules/

This will hold ‘sub-classes’ or modules. In our example we will have 3. A different class for the front-end, the dashboard and the network admin.

/wp-content/plugins/my-plugin-dir/public_html/

Place the ‘view’ files here. These will be plain html files where we will place shortcodes (explanation later) that we can manipulate

/wp-content/plugins/my-plugin-dir/public_html/css/

hmmm… should be self explanatory icon wink Directory Structure These are your own css files, one for each view file, remember any 3rd party css files will go into /wp-content/my-plugin-dir/application/includes

/wp-content/plugins/my-plugin-dir/public_html/js/

This is the same as above, place only your javascript files here.

/wp-content/plugins/my-plugin-dir/public_html/images/

And once again, place only your images here.

The next mission is the naming scheme. This will name your classes, your html files, css files and scripts. What I tend to do is use camel case naming scheme, so for the plugin my-plugin-dir I would use MPDir or as its short WPMyPlugin. Camel case can look ugly at first, I hated it a few years ago, but it has now grown on me. The main rule of thumb when choosing a name is that its:
1) short
2) unique as possible
For this example I’m going to use

WPMyPlugin

. Its short enough for me and should be unique enough for an example plugin.

Your main plugin file – index.php

So now we have our directory structure in place, don’t worry if it doesn’t make sense now – it will later icon wink Your main plugin file   index.php Whats next is our main plugin file – the ‘router’ – the one that will control our classes and register our plugin within wordpress. This file is called

index.php

and is placed in the

/wp-content/plugins/my-plugin-dir

directory.

First and foremost is to register our plugin with wordpress, and this wordpress specific code has to go at the very top of our plugin:

<?php
/**
 * Plugin Name: coombesy
 * Plugin URI: http://david-coombes.com
 * Description: main plugin for this site
 * Author: Daithi Coombes https://www.odesk.com/users/~~d7c1d61dd3fd4c18
 * Version: 0.1
 * Author URI: https://www.odesk.com/users/~~d7c1d61dd3fd4c18
 *
 * @package coombesy
 */

Everything there should be pretty self explanatory, and more can be found on wordpress.org Writing a plugin. So change the values to suit your needs, then log into your network admin and you should see your plugin listed. You should be able to activate/de-activate it – if you can’t then stop and leave a comment before continuing.

Right now our plugin does nothing, has unused directories, but next we’ll write our main class…

Our Main Class – WPMyPlugin.class.php

First of all the core code for our main class, then an explanation. Notice I have named the file:

WPMyPlugin.class.php

And this file is placed in the folder

/wp-content/plugins/my-plugin-dir/application
/**
 * Description of WPMyPlugin
 *
 * @author daithi
 * @package WPMyPlugin
 */
class WPMyPlugin {

	/**
	 * constructor
	 */
	public function __construct() {
		;
	}

	/**
	 * Is called for front end after wp has loaded.
	 *
	 * See @see WPMyPlugin::init_admin() for the admin init
	 */
	public function init(){
		$this->load_styles();
		$this->load_scripts();
	}

	/**
	 * Is called for front end after wp has loaded.
	 *
	 * See @see WPMyPlugin::init() for the frontend init
	 */
	public function init_admin(){
		;
	}

	/**
	 * Loads javascript files.
	 */
	private function load_scripts() {
		;
	}

	/**
	 * Loads css files
	 *
	 * @return void
	 */
	private function load_styles() {
		;
	}
}

So in this class we have 4 methods:

  • construct – is called when class is constructed first
  • init – this will be called on the front end when wordpress has loaded
  • init_admin – this will be called in the back end when wordpress has loaded
  • load_scripts – this will load required javascript files
  • load_styles – this will load required css files

As a rule of thumb, anything you want to run on every wordpress page gets put in here. Since our plugin is going to have an ajax cron run on every page we will need to register and enqueue that file here. This file is included and then constructed in the index.php file like so:

//includes
require("application/WPMyPlugin.class.php");

//set constants
define("WPMYPLUGIN_DIR", WP_PLUGIN_DIR . "/" . basename(dirname(__FILE__)));
define("WPMYPLUGIN_URL", WP_PLUGIN_URL . "/" . basename(dirname(__FILE__)));

//constuct controllers
$wp_my_plugin = new WPMyPlugin();

//actions
add_action('admin_init', array($wp_my_plugin,'init_admin'));
add_action('init', array($wp_my_plugin, 'init'));

Place this directly underneath the code in index.php. So an explanation:
First we include the main class file.

//includes
require("application/WPMyPlugin.class.php");

The we define our constants, also if we had any global variables they would go here as well

//set constants
define("WPMYPLUGIN_DIR", WP_PLUGIN_DIR . "/" . basename(dirname(__FILE__)));
define("WPMYPLUGIN_URL", WP_PLUGIN_URL . "/" . basename(dirname(__FILE__)));

Now we construct our object

//constuct controllers
$wp_my_plugin = new WPMyPlugin();

And then we call our actions. The admin_init action will run only in the backend and the init action will run only in the front end.

//actions
add_action('admin_init', array($wp_my_plugin,'init_admin'));
add_action('init', array($wp_my_plugin, 'init'));

After you have done that, save it, deactivate, then re-activate your plugin. Post below if there are any errors.

Debug Functions

Here I am posting 3 debug functions that I’ve been carrying aroundyour with me for a while now. The most irritating thing about debugging websites in php, in my opinion, is that you can’t format the debug results for html. So say your working on a website and you can’t remember the key in $_SERVER array for the host. So you quickly get your script to:

print_r($_SERVER);

right? And the result you get looks something like:

Array ( [SERVER_SOFTWARE] => Apache/2.2.20 (Ubuntu) [REQUEST_URI] => / [HTTP_HOST] => david-coombes.loc [HTTP_USER_AGENT] => Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:10.0.2) Gecko/20100101 Firefox/10.0.2 [HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 [HTTP_ACCEPT_LANGUAGE] => en-us,en;q=0.5 [HTTP_ACCEPT_ENCODING] => gzip, deflate [HTTP_CONNECTION] => keep-alive [HTTP_COOKIE] =>..........

Arrgggh, ugly and irritating. So basically all the 3 functions below do is wrap <pre> around the debug calls so that your results are formated for display in the browser. Have an extra look at the ar_print() function. This will print the name of the variable to the screen as well, so if your testing more than one array or object you know which one is which.

This function will print an array or object along with the array/object name.

/**
 * Debug function. Prints an array wrapped inside <pre> tags for easy viewing in
 * html browser. Will print the array variable name as well, this is taken from
 * debug dump using preg_match.
 *
 * @param array $ar the array to print
 * @link http://www.david-coombes.com
 * @copyright open
 * @package daithi-debug
 */
function ar_print($ar) {

	//vars
	$name = "";
	$caller_info = array_shift(debug_backtrace());
	$lines = file($caller_info['file']);
	$line = $lines[$caller_info['line'] - 1];

	//search debug dump for var name
	if (preg_match('/ar_print\\s*\\(\$(\\w+)/', $line, $matches))
		$name = $matches[1];

	//print to stdout
	print "\n<pre>\n";
	print "{$name}\t";
	print_r($ar);
	print "\n</pre>\n";
}

This function will do a var_dump and also print the var/object name as well.

/**
* Debug function. var_dump's an array wrapped inside <pre> tags for easy
* viewing in html browser. Will print the array variable name as well, this is
* taken from debug dump using preg_match.
*
* @param array $ar the array to print
* @link http://www.david-coombes.com
* @copyright open
* @package daithi-debug
*/
function var_print($ar) {

	//vars
	$name = "";
	$caller_info = array_shift(debug_backtrace());
	$lines = file($caller_info['file']);
	$line = $lines[$caller_info['line'] - 1];

	//search debug dump for var name
	if (preg_match('/ar_print\\s*\\(\$(\\w+)/', $line, $matches))
		$name = $matches[1];

	//print to stdout
	print "\n<pre>\n";
	print "{$name}\t";
	var_dump($ar);
	print "\n</pre>\n";
}

This function prints a backtrace to the screen. Your code will continue to run, but this is handy to see things like, if an object is being constructed twice (happens a lot in wordpress) etc.

/**
* Debug function. Prints debug_print_backtrace() between two pre tags.
*
* @link http://www.david-coombes.com
* @copyright open
* @package daithi-debug
*/
function debug_print(){

	print "<pre>\n";
	debug_print_backtrace();
	print "</pre>\n";
}