Codex

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

Migrating Plugins and Themes to 2.7

wp-alert.png
This article, written to accord with WordPress 2.7, is now obsolete. Please take caution when following its contents, as many things may have changed.

Introduction

When a new major version of WordPress is released, such as WordPress 2.1 or 2.2, you may find that your Themes and Plugins no longer work the way you are used to. It could be that they are completely broken, because something in WordPress that was fundamental to them changed, but it's also possible that you can get them working again by updating some settings, or maybe just a small edit.

This article is part of a series on Migrating Plugins and Themes. It covers changes between WordPress Version 2.6 and Version 2.7, and what you need to do to Plugins and Themes to get them working in Version 2.7.

If you are the author of your Theme or Plugin, or if you have modified or customized your Theme, then this article will help you upgrade your Theme/Plugin for 2.6. If your Theme or Plugin is distributed publicly, after getting it working you may want to add it to the Compatibility lists above, so your users will know it is working and which version they should be running.

Fixing Up Your Theme or Plugin

The following sections describe changes to WordPress that might affect your theme or plugin.

Themes

Enhanced Comment Display - Threading, Paging, etc.

Comments have many new features in WordPress 2.7, such as threading, nesting, paging, etc. They are built in, assuming that your theme supports them. For details on how to update your theme to take advantage of these new features, please see the Enhanced Comment Display article.

Post Classes

WordPress 2.7 includes a new function for post classes, which will help theme authors perform simpler styling. The function is, appropriately enough, called post_class().

To use this function in a theme, you will simply add it to the Loop in a place that makes sense. Most themes encapsulate every post within a DIV of some sort. That DIV usually has a class="post" or something similar. Instead of that class, just add a call to post_class instead. Like so:

<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>

The post_class() outputs the class="whatever" piece for that div. This includes several different classes of value: post, hentry (for hAtom microformat pages), category-X (where X is the slug of every category the post is in), and tag-X (similar, but with tags). It also adds "sticky" for posts marked as Sticky Posts. These make it easy to style different parts of the theme in different ways.

For special cases where you want to add your own classes, post_class supports that too:

<?php post_class('special'); ?>

This will add "special" to the class list. You can either give it a space separated list of classes, or an array of strings with one class each, if your code is more complex and that is more useful.

For displaying posts outside the Loop or in an alternate Loop, the second parameter to the post_class function can be the post ID. Classes will then be determined from that post.

<?php post_class('',$post_id); ?>

Logout from Site

The Template Tag wp_logout_url was added in Version 2.7 to provide a nonced URL for logout purposes. If a theme uses a construct such as /wp-login.php?action=logout to offer the user a logout link that code should be updated to use the wp_logout_url. A good example of the usage of wp_logout_url can be seen in the WordPress Default and Classic themes comments.php and comments-popup.php Templates.

Users will experience a You are attempting to log out of example.com. Please try again. message if the theme does not use wp_logout_url for the logout URL.

Excluding Sticky Posts from Custom Queries

The ability to designate a post as a sticky was added in Version 2.7. If you use a query posts loop, those sticky posts will be returned in your custom queries. But, to prevent the sticky posts from being included, just add caller_get_posts=1 to your query string.

Display the Sticky Post Class

Find:

<div class="post" id="post-<?php the_ID(); ?>">

an add "<?php sticky_class(); ?>" as so:

<div class="post<?php sticky_class(); ?>" id="post-<?php the_ID(); ?>">

Note that this is not necessary if you use the post_class() function, as explained above. Use of post_class() is preferred, but if you happen to need to do it manually, this will let you get the sticky status of a post.

Using specialized header, footer, sidebar templates

The revised hierarchy allows specification of the header, footer, and sidebar templates for a theme. If a name is specified, a specialized header (or footer) will be included. As was true in the past, if the theme contains no header.php (or footer.php) file then the header (or footer) from the default theme will be included.

  • get_header('myheader') will include header-myheader.php
  • get_footer('myfooter') will include footer-myfooter.php
  • get_sidebar('mysidebar') will include sidebar-mysidebar.php

The Search Form Template Tag

In WordPress 2.7, there is a new search form template tag get_search_form(). In order to preserve compatibility with older themes, the template tag will first look to the theme folder to determine if searchform.php exists. If it does, the tag will use that file. If not, it will generate the HTML.

The tag can also be filtered with the get_search_form filter, allowing plugin authors or theme designers to alter the structure of the search form entirely.

Plugins

Uninstall Plugin API

There is a new plugin uninstall in WordPress 2.7 that allows a plugin to uninstall itself, when the user deletes the plugin. There are two uninstall methods that the plugin can implement.

The easiest way is by creating a file in the your main plugin directory named uninstall.php and then storing the uninstall code there. This file will be included when the user selects to "delete" the plugin from the WordPress plugins screen. Ideally, you would simply add code to remove any options or database information your plugin creates. This file does execute under the WordPress umbrella, so you have full access to WordPress functions from here.

The second method of creating an uninstaller is by creating an action hook that will execute the uninstall routines and then using register_uninstall_hook() function to register the hook with WordPress. This method is somewhat more complex and intended for advanced plugin authors only.

Administrative Hooks Added and Removed

The administration menus in WordPress were redesigned again for 2.7, and correspondingly, some plugin hooks (actions and filters) were added and removed. Here is a list (which may be incomplete):

For a thorough listing of changes to filter and action hooks in WP 2.7 see these lists from the Hook Database at adambrown.info

Add to Settings pages

WordPress 2.7 adds a Settings API for inserting settings and setting sections into the existing WordPress settings panels. This means directly in those pages and not as a new page. The functions add_settings_section(), add_settings_field(), register_setting(), unregister_setting() implement this feature. The functions are found in wp-admin/includes/plugin.php and wp-admin/includes/template.php (also see the section below on registering options, which is just part of this API).

Admin Header

The "sidemenu" action has been removed, since the section of the admin page header that used to add items to is no longer there.

There is a new "favorites" menu, using the 'favorite_actions' filter (see wp-admin/includes/template.php, function favorite_actions() near the bottom, to figure out how to use it).

Plugins List Page

There are two filters that let plugins add items to their display on the Plugins page:

  • plugin_action_links_{$plugin} filter -- lets you add a new action to the Actions column for your plugin. Example:
$plugin = plugin_basename(__FILE__); 
add_filter("plugin_action_links_$plugin", 'my_plugin_actlinks' ); 
function my_plugin_actlinks( $links ) { 
 // Add a link to this plugin's settings page
 $settings_link = '<a href="whatevertheurlis">Settings</a>'; 
 array_unshift( $links, $settings_link ); 
 return $links; 
}
  • after_plugin_row_{$plugin_file} filter - this allows you to add something to the end of the row of information displayed for your plugin - like the existing after_plugin_row filter, but specific to your plugin, so it only runs once instead of after each row of the plugin display

Plugins Need to Register Their Options

If your plugin uses the "easy" method of saving options (described in more detail at Creating Options Pages), then in a near-future version of WordPress (and in the current version of WordPress MU), plugins will need to register their options for them to be recognized as valid.

In WordPress, the functions register_setting() and unregister_setting() can be used to do this; these are simple wrappers for the functions that exist now in WordPressMU, add_option_update_handler() and remove_option_update_handler() (the new aliases will be added soon to WPMU as well).

While using these functions will not be required for 2.7, it will be required in a future version for any plugin that uses options.php as its post handler for option updates. So it is a good idea to modify your plugin to take advantage of this now, for forward compatibility.

These functions have several purposes:

  • Whitelist options
  • Register sanitization callbacks
  • In WPMU, prevent admins (who are not necessarily trusted on a WPMU setup that allows anyone to create a blog) from tinkering with private options such as rewrite_rules or active_plugins.

Here's how to use them (read the function documentation for wp-admin/includes/plugin.php for more information):

  • Define a group name for your options, such as 'some-options'
  • Do something like the following in an admin_init action for each setting you want to update:
register_setting('some-options', 'option-1', 'intval');

Where some-options is the name given to your options group. This is the same name used in the settings_field function. This particular setting is named option-1 and intval is a sanitize callback function.

  • Do this in your option update form:
settings_fields('some-options');

settings_fields() outputs all of the hidden fields that options.php will check, including the nonce. You no longer need to setup the page_options hidden field if you use the new API.

If you have used the function check_admin_referer() to secure your forms, you have to change its argument. If you use settings_fields('some-options') to output the nonce, you have to use the following argument ...

check_admin_referer('some-options-options');

... to let WordPress check, if the nonce is correct.

Notice the trailing '-options'!