Stephanie Leary

Writer and WordPress consultant

  • Books
    • Content Strategy for WordPress (2015)
    • WordPress for Web Developers (2013)
    • Beginning WordPress 3 (2010)
  • Blog
    • Fascism Watch (2016-17)
    • Content Modeling for WordPress series
    • WordPress Hidden Gems series
  • Work
    • Portfolio
    • Services
    • WordPress Plugins
    • WordPress Themes
    • Presentations and Interviews
    • on GitHub →
  • About
    • Press Kit
  • Contact
    • Mailing List

Getting tag autocomplete (and other jQuery stuff) to work for visitors

October 4, 2011 Stephanie Leary 3 Comments

The trickiest part of the latest updates to Twenty Links was getting the tag suggest function to work for users who aren’t logged in. I’m pretty much a n00b when it comes to jQuery — JavaScript in general has always been my weakest skill — so I went looking for a handy tutorial, and I found one: Using WordPress built-in tag auto complete script in your Plugins, posted a couple of years ago by Sudar Muthu. That did the trick — but only for logged-in users.

Why it doesn’t work

WordPress handles jQuery requests using the /wp-admin/admin-ajax.php file. Here’s the catch:

The only cave[a]t to this method is that right now the admin-ajax.php file needs you to be logged in and therefore can only be used in admin pages. But in WordPress 2.9 even anonymous users can load admin-ajax.php file. If you need use auto tag completing in blog pages, then you may have to wait till 2.9 is released.

Obviously that was written before 2.9 came out, so it’s not quite accurate. As it turned out, admin-ajax.php does handle requests from anonymous users — but it kicks them back out to a callback function you specify. I didn’t quite understand what was going on until I actually opened the file and read the code. Here’s the relevant bit:

if ( ! is_user_logged_in() ) {

	// [some stuff having to do with autosave]

	if ( !empty( $_REQUEST['action'] ) )
		do_action( 'wp_ajax_nopriv_' . $_REQUEST['action'] );

	die('-1');
}

Translation: if the user isn’t logged in, call functions hooked to the relevant action prefixed with wp_ajax_nopriv_. If there are no such functions, fail with an error message of -1.

Upshot: your users see this.

auto suggest shows -1 when the user types a word

So, in order to get this working for anonymous visitors, you have to use that wp_ajax_nopriv_[something] action.

How it’s done for authenticated users

Reading a little further down in admin-ajax.php, I found the bit that handles tag suggestions:

switch ( $action = $_GET['action'] ) :
// [other stuff]
case 'ajax-tag-search' :
	if ( isset( $_GET['tax'] ) ) {
		$taxonomy = sanitize_key( $_GET['tax'] );
		$tax = get_taxonomy( $taxonomy );
		if ( ! $tax )
			die( '0' );
		if ( ! current_user_can( $tax->cap->assign_terms ) )
			die( '-1' );
	} else {
		die('0');
	}

	$s = stripslashes( $_GET['q'] );

	if ( false !== strpos( $s, ',' ) ) {
		$s = explode( ',', $s );
		$s = $s[count( $s ) - 1];
	}
	$s = trim( $s );
	if ( strlen( $s ) < 2 )
		die; // require 2 chars for matching

	$results = $wpdb->get_col( $wpdb->prepare( "SELECT t.name FROM $wpdb->term_taxonomy AS tt INNER JOIN $wpdb->terms AS t ON tt.term_id = t.term_id WHERE tt.taxonomy = %s AND t.name LIKE (%s)", $taxonomy, '%' . like_escape( $s ) . '%' ) );

	echo join( $results, "n" );
	die;
	break;

OK, so in order to avoid all those die() conditions, we need to set the action to ajax-tag-search, and the taxonomy has to be defined. I looked at Sudar’s code again. Sure enough, the query string sent to jQuery.suggest() includes both those things: ?action=ajax-tag-search&tax=post_tag. It’s only failing because the user never makes it this far if they’re not logged in. Even if they did get here, this code does an additional check to see if the user can assign tags: if (!current_user_can($tax->cap->assign_terms)). We’ll need to get rid of that in the anonymous version of the function.

Duplicating the function for visitors

I went back to reading about the nopriv callbacks. What I needed to do was define the function that would fetch tags from the database, just like the code in admin-ajax.php, and hook it to the wp_ajax_nopriv_ajax-tag-search action.

Here’s the code I added to the functions.php file, just after Sudar’s code:

// autocompletion for non-logged-in users
add_action('wp_ajax_nopriv_ajax-tag-search', 'add_autosuggest_20links_callback');

// cribbed from admin-ajax.php
function add_autosuggest_20links_callback() {
	global $wpdb;
	if ( isset( $_GET['tax'] ) ) {
		$taxonomy = sanitize_key( $_GET['tax'] );
		$tax = get_taxonomy( $taxonomy );
		if ( ! $tax )
			die( '0' );
	} else {
		die('0');
	}

	$s = stripslashes( $_GET['q'] );

	if ( false !== strpos( $s, ',' ) ) {
		$s = explode( ',', $s );
		$s = $s[count( $s ) - 1];
	}
	$s = trim( $s );
	if ( strlen( $s ) < 2 )
		die; // require 2 chars for matching

	$results = $wpdb->get_col( $wpdb->prepare( "SELECT t.name FROM $wpdb->term_taxonomy AS tt INNER JOIN $wpdb->terms AS t ON tt.term_id = t.term_id WHERE tt.taxonomy = %s AND t.name LIKE (%s)", $taxonomy, '%' . like_escape( $s ) . '%' ) );

	echo join( $results, "n" );
}

It’s exactly the same as the section from admin-ajax.php, minus the capability check and the surrounding switch.

And it works! See it in action on my links site. Grab the Twenty Links theme to see the completed functions.php file.

WordPress jquery

Comments

  1. Jared says

    October 4, 2011 at 10:48 am

    I’m just letting you know in advance that I plan on stealing this for Tasty ;)

    Reply
    • Stephanie says

      October 4, 2011 at 10:54 am

      I expected you would!

      Reply
  2. Alex says

    March 11, 2014 at 12:43 pm

    Great!!! I was looking exactly for this. Thank you!

    Reply

Leave a Reply to Alex Cancel reply

Your email address will not be published. Required fields are marked *

Fascism Watch

The Fascism Watch is a daily(ish) news roundup. View all the previous Fascism Watch posts »

Latest WordPress Book

Content Strategy for WordPress

A short book for content strategists and managers on implementing a complete content strategy in WordPress: evaluation, analysis, content modeling, editing and workflows, and long-term planning and maintenance.

Read the sample chapter

Kindle Nook iBooks Kobo Smashwords

WordPress for Web Developers

WordPress for Web Developers (9781430258667)

This is a book for professional web designers and developers who already know HTML and CSS, and want to learn to build sites with WordPress. The book begins with a detailed tour of the administration screens and settings, then digs into server-side topics like performance and security. The second half of the book is devoted to development: learning to build WordPress themes and plugins.

This is the second, much-revised and updated edition of Beginning WordPress 3, with a more accurate title. Everything’s been updated for WordPress 3.6.

WordPress for Web Developers is out now. See what's inside...

The best WordPress features you’ve never noticed

  • WordPress Hidden Gems: Screen Options
  • WordPress Hidden Gems: Bulk Edit
  • WordPress Hidden Gems: Private Status
  • WordPress Hidden Gems: Dashboard Feed Readers
  • WordPress Hidden Gems: Options.php

Content Modeling for WordPress series

  • Content modeling for WordPress, part 1: analyze content
  • Content modeling for WordPress, part 2: functional and organizational requirements
  • Content modeling for WordPress, part 3: a sample content model

This is an excerpt from Content Strategy for WordPress.My latest books are Content Strategy for WordPress (2015) and WordPress for Web Developers (2013). Sign up to be notified when I have a new book for you.

Copyright © 2021 Stephanie Leary