Codex

Interested in functions, hooks, classes, or methods? Check out the new WordPress Code Reference!

User:Carthik/Plunge into Plugins


..with due apologies to Mark Pilgrim who prefers diving in, we hear :)

Introduction

WordPress beleives in keeping it simple, and a lot of thought goes into including new functionality as a part of the standard WordPress code (or the 'core' of WordPress), in order to keep WordPress fast and lightweight. Users can extend the functionality provided by WordPress by using plugins. You can also write your own plugins, to fill in the gaps that you see, or to do that special thing with your blog. This article will guide you through the process, explaining the basics and going over a few examples.

So, to begin with, let us define a plugin, shall we?

WordPress Plugin 
A WordPress plugin is a program, or a set of one or more functions, written in the PHP scripting language, that adds a specific set of features or services to the WordPress weblog, which can be seamlessly integrated with the weblog using access points and methods provided by the WordPress Plugin Application Program Interface (API).

That said, not every file with a few functions in it can call itself a WordPress Plugin. The following are essential requirements of a WordPress Plugin:

Requirements:

  1. A plugin can be contained in a single file, or in a set of files. All plugin file(s) should be placed in the wp-content directory of the WordPress weblog.
  2. The first few lines of all plugins should adhere to the standards specified in this document.
  3. The users should be able to activate and use the plugin from the "Plugin" menu in the weblog's administrative interface. Specifically, a plugin should not require users to modify the WordPress source code.
  4. The user should be able to set all the preferences and variables required by the plugin using the plugin's own option page, without editing the source code for the plugin.

In addition to these requirements will see some recommended practices and standards later in this document. Next, let us look at the WordPress Plugin API

Plugin API

WordPress provides access points for your plugins. These access points, also known as hooks, can be used by plugins to extend the base functionality.

Plugin File Structure

A WordPress Plugin file should have the following structure :

<?php
/*
Plugin Name: Name_Of_The_Plugin
Plugin URI: URI_Of_Page_Describing_Plugin_and_Updates
Description: A_Brief_Description_Of_The_Plugin
Version: The_Plugin's_Version_Number
Author: Name_Of_The_Plugin_Author
Author URI: URI_Of_The_Plugin_Author
*/

You may also wish to add a GPL template, to explicitly mention that the plugin is released under the same licence as WordPress.

/*  Copyright 2004  PLUGIN_AUTHOR_NAME  (email : PLUGIN AUTHOR EMAIL)

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

These two sections can then be followed by the function definitions and the actual plugin code.

If the Plugin consists of more than one file, then the above comments must be placed at the beginning of the .php file which will reside in the wp-content/ directory. This file usually has the "main" functions, and includes or requires the other files used by the Plugin.

Hooks

There are two types of hooks:

Filter Hooks 
Filter Hooks enable the addition and removal of text-formatting filter-functions which act upon specified data(usually text). These enable plugins to modify content or text on-the-fly.
Action Hooks 
Action Hooks enable the addition and removal of functions whose execution will be triggered by a core WordPress event. These enable plugins to execute functions each time the specified event occurs.

Based on the type of hook used, plugin functions can be classified into two categories:

Filters 
Filters are functions that use WordPress filter hooks to modify content or text
Actions 
Actions are functions that specify additional events that can occur triggered by core WordPress events

Filter Hooks

You can use a filter hook by using the add_filter() function provided by WordPress.

add_filter('filter_hook', 'filter_function_name' [,priority]);

where,

  1. filter_hook is a Filter Hook provided by WordPress
  2. filter_function_name is the name of the function that you want to use on the content specified by filter_hook. This can be a standard php function, a function present in the WordPress core, or a function defined by you in the plugin file.
  3. priority is an optional integer argument that can be used to specify the relative priority with which filters must be applied. If you do not specify this argument, the default priority of 10 is assumed. A filter with a priority of 1 is applied before a filter of priority 2, so the smaller the integer, the higher the priority.

Example usage :

Using the following line of code in a plugin:

add_filter('the_title', 'strtoupper', 9);

Will make all the characters in the title of all posts to their upper case characters, by using the PHP function strtoupper

Likewise, you can also remove filters added by WordPress by default if you so desire, by using the remove_filter() function, which is identical in syntax to the add_filter() function, as shown below: remove_filter('filter_hook', 'filter_function_name' [,priority]); You may want to remove the filters WordPress applies by default to ensure that your own filter plugin works properly, or to stop WordPress from modifying content in a specific manner.

List of Available Filter Hooks

Some of the template tags available in WordPress, which return or echo some form of data or content are Filter Hooks. The following is a list of the filter hooks to format and process data before presenting it to browser:

author_email 
TBD
bloginfo 
TBD
category_description 
TBD
comment_author 
TBD
comment_content_presave 
TBD
comment_edit_pre 
TBD
comment_email 
TBD
comment_excerpt 
TBD
comment_save_pre 
TBD
comments_number 
TBD
comment_text 
TBD
comment_url 
TBD
content_edit_pre 
TBD
content_save_pre 
TBD
default_content 
TBD
default_excerpt 
TBD
default_title 
TBD
excerpt_edit_pre 
TBD
excerpt_save_pre 
TBD
format_to_edit 
TBD
format_to_post 
TBD
link_rating 
TBD
list_cats 
TBD
loginout 
TBD
phone_content 
TBD
post_comment_text 
TBD
posts_where 
TBD
query_string 
TBD
register 
TBD
rewrite_rules 
TBD
rewrite_rules_array 
TBD
sanitize_title 
TBD
single_post_title 
TBD
stylesheet 
TBD
template 
TBD
the_category 
TBD
the_category_rss 
TBD
the_content 
TBD
the_date 
TBD
the_excerpt 
TBD
the_excerpt_rss 
TBD
the_posts 
TBD
the_time 
TBD
the_title 
TBD
the_title_rss 
TBD
the_weekday 
TBD
the_weekday_date 
TBD
title_edit_pre 
TBD

Action Hooks

You can use an action hook by using the add_action() function provided by WordPress.

add_action('action_hook', 'action_function_name' [,priority]);

where,

  1. action_hook is an action hook provided by WordPress. Some action hooks pass you an argument that you can use in the 'action_function_name' function.
  2. action_function_name is the name of the function that you want to be executed following the event specified by the action_hook. This can be a standard php function, a function present in the WordPress core, or a function defined by you in the plugin file.
  3. priority is an optional integer argument that can be used to specify the relative priority with which actions must be executed. If you do not specify this argument, the default priority of 10 is assumed. A filter with a priority of 1 is applied before a filter of priority 2, so the smaller the integer, the higher the priority.

Example usage :

Using the following line of code in a plugin:

add_action('publish_post', 'sleep(5)', 9);

Will result in WordPress going to sleep (doing nothing) for 5 seconds, after a new post is published, by using the PHP function sleep

Likewise, you can also remove actions executed by WordPress by default if you so desire, by using the remove_action() function, which is identical in syntax to the add_filter() function, as shown below: remove_action('action_hook', 'filter_function_name' [,priority]); You may want to remove some actions WordPress applies by default to ensure that your own action plugin works properly, or to stop WordPress from modifying content in a specific manner.

List of Available Action Hooks

The following is a list of the available action hooks:

admin_footer', );
admin_head', );
admin_menu', );
comment_post', $comment_ID);
delete_comment', $comment);
delete_post', $post_id);
edit_comment', $comment_ID);
edit_form_advanced', );
edit_page_form', );
edit_post', $post_ID);
pingback_post', $comment_ID);
private_to_published', $post_ID);
publish_phone', $post_ID);
publish_post', $post_ID);
save_post', $post_ID);
shutdown', );
simple_edit_form', );
switch_theme', 'Default');
switch_theme', get_current_theme());
trackback_post', $wpdb->insert_id);
wp_footer', );
wp_head', );
wp_meta', 1);
wp_set_comment_status', $comment_id);

Settings and Options

You may need to store variables that remain after your script ends (options, for example.) WordPress allows you to define, update and get any option, including your own. The functions that enable you to do this are listed below.

As with your functions, make sure your option names do not conflict with other values WP may be using. A good way to do this is to prefix them with a sufficiently unique string, such as your program's short name or your initials.

Add option: add_option($name, $value, $description, $autoload)

$name
Required (string). Name of the option to be added.
$value
Optional, defaults to " (string). The variable to be stored against your function's name key.
$description
Optional, defaults to " (string).
$autoload
Optional, defaults to 'yes' (boolean or string?).

(Describe what happens in case of naming conflicts here. Overwrite?)

Get option: get_option($option)

$option
Required (string).

Update option: update_option($option_name, $newvalue)

$option_name
Required (string).
$newvalue
Required (string).

User Interfaces

Want to make functions available to use in templates?All plugin functions are available to be called from templates by default. Simple.

Want an admin screen? Use add_options_page($page_title, $menu_title, $access_level, $file).

$page_title
Required (string). The title of your options page.
$menu_title
Required (string). Your tab name in the Options panel.
$access_level
Required (integer). Minimum user level to access options.
$file
Required(string). File to load in Options panel tab.

Somewhere in your plugin, add this function:

function your_function_name_here() {
	if (function_exists('add_options_page')) {
		add_options_page('optionspagetitle', 'optionspagename', minuserlevel, basename(__FILE__));
		}
	}

In the last few lines (when adding hooks), add:

add_action('admin_head', 'your_function_name_here');

To check if a plugin is being loaded in an admin page, use the boolean is_plugin_page().

PHP Tips

Self-submitting Scripts

To make a form-displaying script process itself, check for form variables and, if they're available, call the processing function.

To check if a page is being requested as a result of a form action, one way is to use a hidden field in the form (named 'submitted', for example). Then in the first lines of your PHP script, use either isset($foo), which returns TRUE if a variable has been initialized, or is(empty($foo)), which is almost the same thing (see PHP documentation for the distinction).

Form with hidden element:

<?php
echo '
<form name="example" action="' . $_SERVER[PHP_SELF] . '" method="post">
Text: <input type="text" name="text" /><br />
<input type="hidden" name="submitted" />
<input type="submit" value="Go!" />
<form>
'; ?>

To check for your hidden form element:

isset($_POST['submitted']) /* For method=POST */
isset($_GET['submitted']) /* For method=GET */
isset($_REQUEST['submitted']) /* For either type of form */


Alright, so here we go...before you left, mother asked you to remember the following:

  1. general
    1. if(!function_exists('dys_function_al')....
    2. use your initials to ensure your functions don't clash with others
    3. is_plugin_page(); //is_nt r_boren cool?
  2. admiral
    1. add_options_page($page_title, $menu_title, $access_level, $file)
    2. add_option() and delete_option()
    3. load_plugin_textdomain($domain) --Steal write-up from boren.nu without accredition ;)
    4. need a taxonomy of plugins
  3. lieutenants

Database Tips

Reading is Cheap, Writing is Expensive

Databases are exceptionally good at fetching data and giving it to you, and these operations are (usually) lightning quick. Making changes to the database, though, is a more complex process, and computationally more expensive. As a result, try to minimize the amount of writing you do to the database. Get everything prepared in your code first, so that you can make only those write operations that you need.

SELECT Only What You Need

Even though databases fetch data blindingly fast, you should still try to reduce the load on the database by only selecting that data which you need to use. If you need to count the number of rows in a table don't SELECT * FROM, because all the data in all the rows will be pulled, wasting memory. Likewise, if you only need the post_id and the post_author in your plugin, then just SELECT those specific items, to minimize database load.

Remember: hundreds of other processes may be hitting the database at the same time. The database and server each have only so many resources to spread around amongst all those processes. Learning how to minimize your plugin's hit against the database will ensure that your plugin isn't the one that is blamed for abuse of resources.


  • Need a Big Fat List of Formatting Functions