Автозаполнение или автоподсказка из списка заголовков записей
Я хочу добавить функцию автозаполнения или автоподсказки в (поисковую) форму:
Когда пользователь начинает вводить текст, форма должна предлагать заголовки записей, содержащие совпадающий текст.
Также я хотел бы отображать некоторые метаданные (число), которые я сохранил для каждой пользовательской записи. Пример:
Если я введу "A", должны появиться подсказки "Яблоки (13), Трубкозубы (51), Астронавты (21)" и т.д.

Да, это возможно.
Вы можете использовать jQuery Auto Suggest, который включен в WordPress http://codex.wordpress.org/Function_Reference/wp_enqueue_script
С его помощью можно создать форму, которая выполняет Ajax-запрос к обработчику URL Ajax. К которому вы можете подключиться через add_action. http://codex.wordpress.org/AJAX_in_Plugins
Таким образом, можно выполнить Ajax-поиск, а затем на стороне действия просто выполнить get_posts для сопоставления заголовков или сырой SQL-запрос. И вернуть то, что требуется.
Это должно помочь. Если у меня будет время в ближайшее время, я могу написать полное решение с кодом. Но основная часть - это целый плагин для реализации поиска.
Редактирование: Вот пример, что-то вроде этого должно работать, не тестировал, просто написал навскидку. Обновление: Экранировать введенный текст, ограничить по типу записи и только опубликованным записям.
Редактирование 2012-11-21: исправлена опечатка в примере кода.
add_action('wp_enqueue_scripts', 'se_wp_enqueue_scripts');
function se_wp_enqueue_scripts() {
wp_enqueue_script('suggest');
}
add_action('wp_head', 'se_wp_head');
function se_wp_head() {
?>
<script type="text/javascript">
var se_ajax_url = '<?php echo admin_url('admin-ajax.php'); ?>';
jQuery(document).ready(function() {
jQuery('#se_search_element_id').suggest(se_ajax_url + '?action=se_lookup');
});
</script>
<?php
}
add_action('wp_ajax_se_lookup', 'se_lookup');
add_action('wp_ajax_nopriv_se_lookup', 'se_lookup');
function se_lookup() {
global $wpdb;
$search = like_escape($_REQUEST['q']);
$query = 'SELECT ID,post_title FROM ' . $wpdb->posts . '
WHERE post_title LIKE \'' . $search . '%\'
AND post_type = \'post_type_name\'
AND post_status = \'publish\'
ORDER BY post_title ASC';
foreach ($wpdb->get_results($query) as $row) {
$post_title = $row->post_title;
$id = $row->ID;
$meta = get_post_meta($id, 'YOUR_METANAME', TRUE);
echo $post_title . ' (' . $meta . ')' . "\n";
}
die();
}

Вау, спасибо, Барри! Я попробую, это нужно вставить в functions.php, верно? Я изменю необходимые части и посмотрю, что получится

Теоретически да, в functions.php. Я бы поместил это в плагин, чтобы не мешалось. Если вставлять прямо в functions.php, то можно провести оптимизацию, так как часть этого кода может быть применена к уже существующим функциям в functions.php (зависит от темы, конечно)

Обновил код, включив like_escape. Я не использую % в начале, потому что нужно искать посты, заголовки которых начинаются с введенной буквы. Это не глобальное совпадение. Мой рабочий код использует $_REQUEST['q'] без дополнительных параметров для jQuery suggest. Q имитирует то, что используют поисковые системы.

Это работает... почти! Я должен был уточнить, что хотел получить данные из произвольного типа записи (custom-post-type), сейчас отредактирую свой вопрос.

@BarryCarlyon Пожалуйста, не редактируйте каждую мелочь. Если вы сделаете 10 правок, вопрос автоматически станет "вики сообщества", и вы потеряете все очки репутации. А нам нужно больше пользователей с хорошими ответами и минимальным уровнем репутации для таких задач, как редактирование, добавление вики и т.д. И кстати, exit;
всегда быстрее, чем die();
:)

Последнее замечание: Не сохраняйте переменные, которые используете только один раз ($id = $row->ID
). Используйте их напрямую.

@kaiser в документации WordPress: http://codex.wordpress.org/AJAX_in_Plugins указано, что для этого следует использовать die();. В противном случае я бы согласился

Привычка делать $x = $row->x, обычно в моих циклах выполняется гораздо больше действий

Отлично! Просто из любопытства, есть ли способ настроить это так, чтобы можно было напрямую передавать тип записи для получения? У меня есть несколько разных типов записей, для которых это может понадобиться. Сейчас рассматриваю вариант установки transient при настройке текстового поля с последующим его получением в этом скрипте...

Конечно, просто замените "AND post_type = \'post_type_name\'" на код для получения post_type_name из $_REQUEST (с соответствующей экранизацией) и убедитесь, что ваша форма поиска включает скрытое поле с вашим значением. Например: "<input type="hidden" name="post_type" value="somename" />" и подставьте это в запрос
