WordPress 通过代码实现 Ajax 自动完成搜索

本教程适合想要在WordPress中实现自动完成搜索的用户,在此我们可以完全控制返回的匹配项。

我们将对标准WordPress搜索应用自动完成功能,但是代码具有高度的灵活性,因此您可以根据需要自定义查询。无论是按自定义文章类型、文章元、分类还是针对完全不同类型的内容(例如用户或数据库中的数据)的更具体的查询。您还可以轻松地将自动完成功能应用于自定义搜索输入,而不仅限于标准的WordPress搜索。

我们将做些什么

自动完成是一个UI框,出现在搜索字段下方,显示您键入时的匹配项。点击匹配项后,浏览器会将您转到该网站的永久链接。这为最终用户提供了一种浏览内容的更快方法,因为他们不需要绕开您的搜索结果页面。在用户键入内容时,我们将使用AJAX不断更新匹配项。

自动完成是在jQuery UI Autocomplete的帮助下生成的,jQuery UI Autocomplete是WordPress中默认包含的脚本。

设置代码

您将需要在主题functions.php文件或有效的插件PHP文件中添加代码。本教程基于将其添加到主题中。请调整路径以适合您的项目。

第一步是创建一个Javascript文件,其中将包含我们的代码以触发自动完成。至于本教程,我将在主题的assets/js/文件夹中创建一个空文件autocomplete.js。放置文件的位置取决于您,只需记住调整以下路径即可。在WordPress中将该文件正确排队后,我们将返回该文件。

引入脚本和样式

我们需要引入自动完成的Javascript文件,还需要确保引入jQuery和jQuery UI Autocomplete。此外,WordPress不包含jQuery UI库的任何样式,因此我们还需要从Google CDN引入jQuery UI的样式表。当然,这是可选的。您可以通过其他方式添加CSS,或者您可能希望自己设置样式。

我们将所有脚本和样式放入一个函数挂载到 wp_enqueue_scripts

functions.php

add_action('wp_enqueue_scripts', function() {
     wp_enqueue_script('autocomplete-search', get_stylesheet_directory_uri() . '/assets/js/autocomplete.js', 
         ['jquery', 'jquery-ui-autocomplete'], null, true);
 });

上面的函数调用wp_enqueue_script()将添加具有正确依赖关系的新创建的Javascript文件(该数组作为第三个参数)。这可以确保WordPress在我们的WordPress实例中添加jQuery和jQuery UI Autocomplete脚本。

接下来,我们需要提供一些可从自动完成脚本访问的变量。我们需要知道AJAX URL,并且还想添加一个安全性随机数。我们可以这样使用wp_localize_script():

functions.php

add_action('wp_enqueue_scripts', function() {
     wp_enqueue_script('autocomplete-search', get_stylesheet_directory_uri() . '/assets/js/autocomplete.js', 
         ['jquery', 'jquery-ui-autocomplete'], null, true);
     wp_localize_script('autocomplete-search', 'AutocompleteSearch', [
        'ajax_url' => admin_url('admin-ajax.php'),
        'ajax_nonce' => wp_create_nonce('autocompleteSearchNonce')
    ]);
});

wp_localize_script()函数将创建一个AutocompleteSearch具有两个属性(ajax_urlajax_nonce)的全局Javascript变量。这样,我们就可以在自动完成的Javascript文件中获取WordPress AJAX URL的值,例如AutocompleteSearch.ajax_url

最后,我们需要添加一些样式。如前所述,WordPress没有附带任何jQuery UI样式,因此我们需要自己添加一些样式。我选择通过Google CDN添加样式表。但是我们需要知道jQuery UI版本号才能获取其样式表。我们可以对版本号进行硬编码,但是我不喜欢对任何内容进行硬编码。在下面,您会发现一个很好的技巧,可以利用WordPress中存储的jQuery UI版本信息。

functions.php

add_action('wp_enqueue_scripts', function() {
     …
 $wp_scripts = wp_scripts(); wp_enqueue_style('jquery-ui-css',     '//ajax.lug.ustc.edu.cn/ajax/libs/jqueryui/' . $wp_scripts->registered['jquery-ui-autocomplete']->ver . '/themes/smoothness/jquery-ui.css',     false, null, false );
 });

我们使用wp_enqueue_style()注册的CDN路径作为第二个参数来注册并添加新的样式表。为了获取有效的jQuery UI版本号,我们使用该函数提供的信息wp_scripts()

这就是我们引入脚本所需的一切!

编写自动完成的Javascript

让我们回到我们的autocomplete.js文件。我们知道在加载该脚本时,已经加载了jQuery和jQuery UI Autocomplete,并且我们还可以访问带有必需信息的全局变量。让我们从设置jQuery文档ready函数开始,以确保在DOM准备好之后运行我们的代码。

autocomplete.js

jQuery(function($) {
     // All code in here
});

如果我们查看过jQuery UI Autocomplete的文档,我们就会知道我们需要制作一个针对输入字段的jQuery选择器并在其autocomplete()上运行该函数。

在这一点上,您可以调整代码以适合您的需求。本教程将自动完成功能应用于标准WordPress搜索字段(通常通过包含搜索模板或作为小工具将其添加到主题中)。搜索输入的类名称可能因主题而异。但是您可能想要定位自定义输入字段或在特殊模板中进行搜索。您需要做的就是更改jQuery选择器以定位所需的输入。

在我的主题中,标准WordPress搜索字段输入具有的类.search-field。我还添加了父表单类名,以进一步缩小范围,因此我们不会冒着自动完成功能被应用到使用同一类的其他事情的风险。

根据自动完成文档,我们可以在属性中执行AJAX调用(该属性source必须返回要在自动完成中显示的项目数组)。我们将使用jQuery的Ajax函数来做到这一点:

autocomplete.js

jQuery(function($) {
     $('.search-form .search-field').autocomplete({
         source: function(request, response) {
             $.ajax({
                 dataType: 'json',
                 url: AutocompleteSearch.ajax_url,
                 data: {
                     term: request.term,
                     action: 'autocompleteSearch',
                     security: AutocompleteSearch.ajax_nonce,
                 },
                 success: function(data) {
                     response(data);
                 }
             });
         },
     });
 });

在第二行代码,我们告诉jQuery UI自动完成功能要在哪个输入字段上应用自动完成功能。更改此选择器以适合您的需求。

以最简单的形式,“自动完成”会期望source属性包含一组项目对象。在这里,我们创建一个具有两个参数的函数;request包含有关我们输入的值(request.term)的信息,response这是我们需要调用并提供数据的回调函数。这就是我们在AJAXsuccess函数的13行代码。

AJAX调用本身是非常标准的。我们将数据类型定义为JSON –这很重要,否则jQuery UI Autocomplete将无法解析结果。当我们访问ajax_url全局变量url时,我们更早地本地化了脚本AutocompleteSearch。当data我们传递信息对象时。该action属性是强制性的,对于下一步是必需的-标识PHP中的此特定AJAX请求。为了安全起见,我们还将输入的术语传递到输入和随机数中。

就是这样的sources属性。我们还需要在自动完成脚本中添加另一件事。在jQuery UI Autocomplete中,默认情况下,选择一个项目会自动使用所选元素自动填充输入。从列表中选择项目时,我们希望将用户重定向到文章的URL。因此,我们向该select属性添加了一个函数:

autocomplete.js

                …
                success: function(data) {
                    response(data);
                }
            });
        },      
        select: function(event, ui) {
            window.location.href = ui.item.link;
        },
    });
});

在项目数组中,我们将从AJAX调用返回(我们将在下一个内容中编写),每个项目都是具有属性的对象。我们将为每个项目(ui.item)添加一个自定义属性link,其中将包含每个文章的永久链接。我们将此URL传递到 window.location.href,它将触发浏览器重定向。

这就是Java语言部分的全部内容!剩下的全部就是编写PHP部分,并通过该操作侦听AJAX请求autocompleteSearch

将PHP中的结果返回到AJAX请求

为了编写响应特定AJAX请求的函数,我们使用了钩子wp_ajax_{action}(已登录的访问者)和wp_ajax_nopriv_{action}(未登录的访问者)。我们autocompleteSearch在上面的AJAX请求中定义了操作。

让我们在以下位置进行设置functions.php(或在PHP中添加代码的任何位置):

functions.php

add_action('wp_ajax_nopriv_autocompleteSearch', 'awp_autocomplete_search');
add_action('wp_ajax_autocompleteSearch', 'awp_autocomplete_search');
function awp_autocomplete_search() {
    // echo result
    die();
}

使用上面的代码,我们将相同的函数钩接到两个AJAX钩上。在挂钩到wp_ajax AJAX挂钩的所有函数中,我们必须确保始终执行die()exit结尾执行,以免回显不希望的输出。我正在使用WordPress的wp_die()函数。

我们可以使用$_REQUEST(从GET和POST请求中都可以使用)从Javascript中获取传递的数据。在我们的Javascript代码中,我们在键’ term‘中传递了输入的术语。这意味着我们可以在中获取它的值$_REQUEST['term']。然后,我们可以基于此执行查询。请记住,我们只想返回与该搜索词匹配的结果。

这是您可以完全更改和调整代码以满足您的需要的另一点。本教程将对文章和页面执行标准查询,但是您可以调整查询或对不同数据执行完全不同的查询。也许您更喜欢或需要执行手动SQL查询(这肯定会提高内存效率)。这里的关键部分是我们最后回显的数组,该数组由Javascript的自动完成代码解析。

functions.php

add_action('wp_ajax_nopriv_autocompleteSearch', 'awp_autocomplete_search');
add_action('wp_ajax_autocompleteSearch', 'awp_autocomplete_search');
function awp_autocomplete_search() {
    check_ajax_referer('autocompleteSearchNonce', 'security');
    $search_term = $_REQUEST['term'];
    if (!isset($_REQUEST['term'])) {
        echo json_encode([]);
    }

    $suggestions = [];
    $query = new WP_Query([
        's' => $search_term,
        'posts_per_page' => -1,
    ]);

    if ($query->have_posts()) {
        while ($query->have_posts()) {
            $query->the_post();
            $suggestions[] = [
                'id' => get_the_ID(),
                'label' => get_the_title(),
                'link' => get_the_permalink()
            ];
        }
        wp_reset_postdata();
    }
    echo json_encode($suggestions);
    wp_die();
}

首先,我们检查随机数是否有效,以在我们的AJAX调用上建立一些安全性。我们可以通过调用函数check_ajax_referer()来做到这一点。我还添加了代码,以确保如果返回的搜索字词为空,我们不会执行繁重的请求。然后,我们应该返回一个空的json编码数组。

上面的示例代码WP_Query对输入的词进行搜索。我们需要将设置posts_per_page-1,以确保我们返回所有匹配项。查看文档,以了解WP_Query是否要进一步调整查询。

然后,我们遍历结果(第#17行),并用匹配项(第#19-23行)填充数组。jQuery UI自动完成功能需要至少具有一定的属性,label以表示应在自动完成功能框中显示的内容。我们还会在键“ link”中传递永久链接,这是我们在Javascript代码中用于重定向用户的方式。

最后,在第#27行我们使用json_encode()来将生成的数组作为JSON输出。

有了此PHP部分,我们的自动完成功能就可以工作了!刷新您的网站并尝试一下!

可选的改进

一个普遍的问题是匹配数太多,自动完成框太大。有两种解决方案。

一种解决方案是将属性添加minLengthautocomplete()Javascript函数中。此属性仅在输入一定数量的字符后才触发自动完成框。例如,在触发自动完成功能之前,我们至少需要3个字符:

autocomplete.js

        …
        select: function(event, ui) {
            window.location.href = ui.item.link;
        },
        minLength: 3,
    });
});

jQuery UI Autocomplete在这里提出了另一个解决方案。它显示了在自动完成框中添加一些CSS来添加固定高度和内部滚动条的示例。

总结和完整代码

我们已成功将自动完成功能添加到WordPress的搜索功能中,在此我们可以完全控制返回的匹配项。它为访问者提供了一种更快的方式来浏览您的内容,因为单击匹配项将直接重定向到该文章,而不是先在搜索结果页面中绕行。在所有WordPress网站中实施自动完成可能并不总是很有意义,但是对于搜索特定内容或在特殊模板中非常有用!

这是完整的最终代码:

functions.php

add_action('wp_enqueue_scripts', function() {
     wp_enqueue_script('autocomplete-search', get_stylesheet_directory_uri() . '/assets/js/autocomplete.js', 
         ['jquery', 'jquery-ui-autocomplete'], null, true);
     wp_localize_script('autocomplete-search', 'AutocompleteSearch', [
        'ajax_url' => admin_url('admin-ajax.php'),
        'ajax_nonce' => wp_create_nonce('autocompleteSearchNonce')
    ]);

    $wp_scripts = wp_scripts(); 
    wp_enqueue_style('jquery-ui-css', 
    '//ajax.lug.ustc.edu.cn/ajax/libs/jqueryui/' . $wp_scripts->registered['jquery-ui-autocomplete']->ver . '/themes/smoothness/jquery-ui.css', 
    false, null, false);
});

add_action('wp_ajax_nopriv_autocompleteSearch', 'awp_autocomplete_search');
add_action('wp_ajax_autocompleteSearch', 'awp_autocomplete_search');
function awp_autocomplete_search() {
    check_ajax_referer('autocompleteSearchNonce', 'security');
    $search_term = $_REQUEST['term'];
    if (!isset($_REQUEST['term'])) {
        echo json_encode([]);
    }

    $suggestions = [];
    $query = new WP_Query([
        's' => $search_term,
        'posts_per_page' => -1,
    ]);

    if ($query->have_posts()) {
        while ($query->have_posts()) {
            $query->the_post();
            $suggestions[] = [
                'id' => get_the_ID(),
                'label' => get_the_title(),
                'link' => get_the_permalink()
            ];
        }
        wp_reset_postdata();
    }
    echo json_encode($suggestions);
    wp_die();
}

autocomplete.js

jQuery(function($) {
    $('.search-form .search-field').autocomplete({
        source: function(request, response) {
            $.ajax({
                dataType: 'json',
                url: AutocompleteSearch.ajax_url,
                data: {
                    term: request.term,
                    action: 'autocompleteSearch',
                    security: AutocompleteSearch.ajax_nonce,
                },
                success: function(data) {
                    response(data);
                }
            });
        },
        select: function(event, ui) {
            window.location.href = ui.item.link;
        },
    });
});

注:本教程出自awhitepixel.com ,由WordPress大学 翻译整理。

© 版权声明
THE END
喜欢就支持一下吧
点赞0赞赏
分享
评论 抢沙发

请登录后发表评论