Interacting with WordPress' Plug-in & Theme API

The WordPress Repository API is the API used to fetch plug-in and theme information for use on your admin pages. For instance it displays the latest plug-ins on the dashboard, allows you to view themes on your theme tab and allows you to search for, and install, plug-ins straight from the repository. In this tutorial we're going to look at how this API works and how it can be used to access information such as your plug-in's rating, how many times it's been downloaded, or even its ReadMe sections. Using this API, for instance, you can host a link on your website that will always point to the latest version of your plug-in or theme.

When WordPress gathers information on plug-ins and themes from the repository it does so by sending a request to one of two URLs.

For plug-ins: http://api.wordpress.org/plugins/info/1.0/

For themes: http://api.wordpress.org/themes/info/1.0/

The request takes the form of an array with an 'action' and 'request' key.

Getting Details of a Plug-in or Theme

When retrieving data about a plugin or theme, the 'action' should be set to plugin_information or theme_information respectively. The value of the request key should be a serialized object with a slug property (the slug of the theme/plug-in) and a field property, which indicates what data we are after (the available fields are detailed below). In the above snippet, $args should be an associative array with keys given by those properties.

The return value from wp_remote_post, $response, may be a WP_Query error or else a genuine response from the repository containing an error message. But if all went well, then the returned plug-in or theme object can be extracted from it with the following:

Querying the Plug-in & Theme Repositories

To retrieve a list of themes/plug-ins that match certain criteria, the action should be set to query_themes or query_plugins. This should be accompanied with an appropriate key (e.g. 'author', to get plugins/themes by a particular author) in the $args array. The possible criteria are given below.

Again (assuming no errors have occurred), the array of matching plug-ins should be given by:

Each theme/plugin object in the array has the same properties as those determined by the fields key in the $args array. The available fields are listed below, as well as the default fields (for *_information queries). Please note that the default values are different for different actions.

Plug-in Properties

As noted above $args is an associative array which can contain the following fields:

slug – (When the action is plugin_information). The slug of the plug-in to return the data for.

browse – (When the action is query_plugins). Takes the values featured, popular or new.

author – (When the action is query_plugins). The author's WordPress username, to retrieve plugins by a particular author.

tag – (When the action is query_plugins). Tag with which to retrieve plugins for.

search – (When the action is query_plugins). A search term, with which to search the repository.

fields – an array with possible fields (listed below) as keys and true or false value to return data for that field or not. The fields that are included make up the properties of the returned object above. The possible fields are (default set to true, unless otherwise stated):

version – latest

author – author name and link to profile

requires – the minimum WordPress version required

tested – the latest WordPress version tested

compatibility – an array which contains an array for each version of your plug-in. This array stores the number of votes, the number of 'works' votes and this number as a percentage.

downloaded – the number of downloads

rating – as a percentage

num_ratings – number of ratings

sections – this is an array with the HTML for each section on the WordPress plug-in page as values, keys can include 'description', 'installation', 'screenshots', 'changelog' and 'faq'.

download_link – points to repository hosted ZIP file of the plugin's latest version

Theme Properties

The themes API request is very similar, although there are slightly different fields available.

slug – (When the action is theme_information) The slug of the theme to return the data for.

browse – (When the action is query_themes). Takes the values featured, new or updated.

author – (When the action is query_themes). The author's username, to retrieve themes by a particular author.

tag – (When the action is query_themes). An array of tags with which to retrieve themes for.

search – (When the action is query_themes). A search term, with which to search the repository.

fields – again an array with a true or false value for each key (field). The fields that are included make up the properties of the returned object above. The possible fields are (default set to true, unless otherwise stated):

In these examples, I have used (for the most part) the default fields – but in a bid to save that little bit of bandwidth, you should explicitly state which fields you do, and don't want.

Caching

This is an excellent example of where caching, specifically transients, can (and should) be used. Caching the data means we won't fetch the information from the repository on every page load – which would slow the site load. As a simple example, when I ran the example above without caching it took 0.522 seconds to retrieve the data (which is respectable). Once I started used transients, it dropped to 0.001 seconds. In any case we don't need to get this information on every page load – in fact there is little reason to update this data more than once a day (or maybe longer).

If you are not sure how to use transients, you can read up on them in this article.

Let's implement transients in a generic function that will retrieve theme information, given a specific theme (and other arguments):

/**
* Returns a theme object given an array $args or WP_Error object if there is an error
* $args should contain a 'slug' key with the theme's name
* and 'fields' key holding an array of fields to retrieve.
*/
function sh_get_theme_information( $args ) {
// Set the $request array
$request = array(
'body' => array(
'action' => 'theme_information',
'request' => serialize((object)$args)
)
);
// Generate a cache key that would hold the response for this request:
$key='sh_theme_'.md5(serialize($request));
// Check transient. If it's there - use that, if not re fetch the theme
if ( false === ($theme = get_transient($key)) ) {
// Theme not found - we need to re-fetch it
$response = wp_remote_post('http://api.wordpress.org/themes/info/1.0/',$request);
if ( is_wp_error($response) )
return $response;
$theme = unserialize(wp_remote_retrieve_body($response));
if ( !is_object($theme) && !is_array($theme) )
return new WP_Error('theme_api_error', 'An unexpected error has occurred');
// Set transient for next time... keep it for 24 hours should be good
set_transient($key, $theme, 60*60*24);
}
return $theme;
}

The basic pattern for retrieving data from any API is broadly the same. Turn a request into a unique, with which to cache the results. Then check if data exists for the key, if it does – great, we can just return that data. Otherwise, fetch the data remotely. Once you've received the response, check for errors, and if there aren't any update the transient and return the newly fetched data.

As a second example, we can construct a function that returns an array of plug-ins by a particular author: