Admin Pointers in WordPress 3.3

WordPress 3.3 is planned for November this year and we published the scope a while ago here on Theme.fm. As mentioned in that post, 3.3 will get a series of UI improvements, one of which is Pointers (or Admin Pointers). We learned about pointers in WordPress a few hours ago from one of Daryl Koopersmith’s changesets so we decided to give it a spin ourselves.

What are Admin Pointers?

Here’s what Jane wrote in the trac ticket for WordPress pointers:

When a new user-facing feature is included in a core update, display a new feature pointer that highlights the new feature a la Facebook, Gmail, etc.

WordPress 3.3 Admin Pointer

Core features are cool, but the exciting thing about pointers is that plugin and theme developers will (hopefully) be able to use them as well. The API at it’s current stage looks quite simple. It’s basically a jQuery widget which you can stick to things like buttons, menus, links and any other elements in the DOM.

The source code is located in wp-includes/js/wp-pointer.js which suggests that pointers could be used outside of the admin panel, which is great. There are not too much details about that yet though, and before the actual 3.3 release, the script may be moved somewhere else, unlike the pointers script and style handle which is probably final: wp-pointer.

Note that WordPress pointers are not available on any stable versions of WordPress yet and is planned for 3.3. You can access the development copy of WordPress via Subversion but you shouldn’t use that in any live environment.

Using Pointers in Your Themes and Plugins

For experimental purposes we decided to give pointers a spin in Twenty Eleven by creating a child theme. Let’s start off by creating a functions.php file for your child theme and adding the following code to include the pointer scripts and styles:

add_action( 'admin_enqueue_scripts', 'my_admin_enqueue_scripts' );
function my_admin_enqueue_scripts() {
    // Using Pointers
    wp_enqueue_style( 'wp-pointer' );
    wp_enqueue_script( 'wp-pointer' );

    // Register our action
    add_action( 'admin_print_footer_scripts', 'my_admin_print_footer_scripts' );
}

function my_admin_print_footer_scripts() {
    // This will run during footer scripts, use jQuery to show the pointer here.
}

This simply tells WordPress to enqueue the pointers script and stylesheet in the admin panel, as well as registers an action that runs during admin_print_footer_scripts — that’s where we’re going to use jQuery to actually show the pointer, let’s do that:

function my_admin_print_footer_scripts() {
    $pointer_content = '<h3>Welcome to Twenty Eleven!</h3>';
    $pointer_content .= '<p>Lorem Ipsum is simply dummy text of the printing <br /> and typesetting industry. Lorem Ipsum has been the <br /> industrys standard dummy text ever since the 1500s!';
?>
<script type="text/javascript">
//<![CDATA[
jQuery(document).ready( function($) {
    $('#menu-appearance').pointer({
        content: '<?php echo $pointer_content; ?>',
        position: 'left',
        close: function() {
            // Once the close button is hit
        }
    }).pointer('open');
});
//]]>
</script>
<?php
}

The usage is not too straightforward. Basically we set a variable to contain our pointer content, that’s the place where you’ll have to localize your strings if you need to. Note that $pointer_content is used inside the javascript block, so make sure you escape/quote the string and we’ll leave that out for brevity.

After the php chunk you’ll see that we’re calling the pointer function in jQuery while providing it with a selector — this is the object in the DOM that you want to apply the pointer to. In our case it’s #menu-appearance which is the id of the Appearance section in the admin menu (you can use Firebug or Chrome’s developer tools to find other elements).

The pointer function is passed a few arguments. You’ll find all of them in the wp-pointer.js file, they’ll hopefully get some inline code comments while being self-explanatory. Anyway, we set the position of our pointer with the position argument and the position of the arrow of our pointer with the arrow argument.

Also note that close argument which is given a function that runs when the close button is hit. We’ll talk about this in a while. The call to .pointer('open') is appended at the end of it all, this will display the pointer on screen.

So now you should end up with something like this:

Twenty Eleven Admin Pointer WordPress 3.3

Sweet, eh? But there’s a problem. The close button works, but as soon as you refresh the page or visit any other section in your admin panel, the annoying pointer pops up again. This is where user settings come in.

Closing Pointers

Daryl’s initial commit suggested using so-called user settings to handle pointer data, which is a mix of cookies and options on a per-user basis in WordPress. The most recent changes though suggest using the user meta table and AJAX calls to close events.

The API for pointers usage in themes and plugins has been postponed to WordPress 3.4 but there’s quite a lot we can learn from how the core implements the “close” feature. Here’s the changeset by Andrew Nacin which shows how AJAX is used and attached to the pointer’s close event.

Conclusion

This post is intended to give you a quick and rough overview of pointers in WordPress 3.3. As already mentioned, you shouldn’t use the trunk version of WordPress in production (on your live websites) and there’s no guarantee that the functionality or API will not changed before the final 3.3 release.

We’ll keep up to date with that ticket and revisit this post with an update as soon as 3.3 is released. Meanwhile you can play around with what we have. I bet that it’ll be quite simple to create a live tour of themes, plugins and WordPress itself by using pointers. What do you think?

Update 22.09.2011: We’ll keep this post updated until the 3.3 release so don’t get used to the API just yet. It seems like user settings wasn’t the best option after all because of the cookie size restrictions. Here’s what we got from Andrew Nacin:

I had a conversation with koopersmith and we plan to switch closing to an XHR call and avoid the user settings API … We don’t want the user settings API to start getting used all over the place. User settings are cool and simple, but bad for one-off features like this, especially when plugins may then extend it. The issue is that the cookie holding that data can only hold so much data (4kb). It’s also why we kept the setting name so short (“p0″).

And here’s also what John O’Nolan from the Core UI team suggested as an alternative color implementation which makes the pointers stand out a little more.

WordPress Admin Feature Pointers

We also went ahead with that tour idea and created this: Theme.fm Experiments: Admin Tour with WordPress Pointers. Quite some good feedback there ;)

Update: as shown in this diff, this changeset and pointed out earlier by Andrew Nacin, dismissed pointers are kept in user meta (in the database) rather than user settings (cookies) and the mentioned code illustrate an elegant way of doing so. The code in this post has been modified to work with the recent changes to the API.

Thank you so much for reading. Leave your thoughts on WordPress Pointers in the comments section below an thank you for staying tuned!