Göra autoslutföra sökningar i WordPress med kod
Den här handledningen är för dig som vill implementera en autoslutförandesökning i WordPress, där vi har full kontroll över de returnerade matchningarna.
Vi kommer att tillämpa ett autoslutförande på den vanliga WordPress-sökningen, men koden är mycket flexibel så att du kan anpassa frågan efter dina behov. Oavsett om det är en mer specifik fråga av en anpassad inläggstyp, inläggsmeta, kategorier eller frågor om helt annan typ av innehåll som användare eller något manuellt från databasen. Du kan också enkelt tillämpa autoslutförandet på en anpassad sökinmatning istället för den vanliga WordPress-sökningen.
Vad vi ska göra
Autoslutförande är en gränssnittsruta som visas under sökfältet och visar matchningarna medan du skriver. När du klickar på en matchning skickar webbläsaren dig till inläggets permalänk. Detta ger slutanvändaren ett snabbare sätt att navigera i ditt innehåll eftersom de inte behöver ta den extra omvägen till din sökresultatsida. Vi kommer att använda AJAX för att kontinuerligt uppdatera matchningarna medan användaren skriver.
Autokompletteringen genereras med hjälp av jQuery UI Autocomplete, ett skript som ingår i WordPress som standard.
Ställer in koden
Du kommer att behöva lägga till koden i antingen temats functions.phpeller en aktiv plugin PHP-fil. Denna handledning bygger på att lägga till den i ett tema. Justera banorna så att de passar ditt projekt.
Det första steget är att skapa en Javascript-fil som kommer att innehålla vår kod för att utlösa autokomplettering. När det gäller denna handledning skapar jag en tom autocomplete.jsfil i mitt temas assets/js/mapp. Var du placerar din fil är upp till dig, kom bara ihåg att justera sökvägarna nedan. Vi återkommer till den här filen när vi har ställt den i kö ordentligt i WordPress.
Manus och stilar i kö
Vi måste ställa vår Javascript-fil för automatisk komplettering i kö och vi måste också se till att ställa jQuery och jQuery UI Autocomplete i kö. Dessutom innehåller WordPress inte någon styling för jQuery UI-bibliotek, så vi måste också ställa en stilmall för jQuery UI från Google CDN. Detta är naturligtvis valfritt. Du kan lägga till CSS på något annat sätt eller kanske du föredrar att styla den själv.
Vi ställer alla skript och stilar i kö i en funktion kopplad till wp_enqueue_scripts:
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);
});
Funktionsanropet [wp_enqueue_script](https://developer.wordpress.org/reference/functions/wp_enqueue_script/)()ovan kommer att lägga till vår nyskapade Javascript-fil med rätt beroenden (matrisen som tredje parameter). Detta säkerställer att WordPress lägger till skripten jQuery och jQuery UI Autocomplete i vår WordPress-instans.
Därefter måste vi tillhandahålla några variabler som vi kan komma åt från vårt autoslutförandeskript. Vi måste känna till AJAX URL och vi vill också lägga till en nonce för säkerheten. Vi kan göra detta genom att använda [wp_localize_script](https://developer.wordpress.org/reference/functions/wp_localize_script/)():
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')
]);
});
Funktionen wp_localize_script()kommer att skapa en global Javascript-variabel AutocompleteSearchmed två egenskaper; ajax_urloch ajax_nonce. Med detta kan vi i vår autokomplettera Javascript-fil hämta till exempel värdet på WordPress AJAX URL med AutocompleteSearch.ajax_url.
Slutligen måste vi lägga till lite styling. Som nämnts kommer WordPress inte med någon jQuery UI-styling inkluderad så vi måste lägga till några själva. Jag har valt att lägga till en stilmall via Google CDN. Men vi behöver veta versionsnumret för jQuery UI för att kunna hämta dess stilmall. Vi skulle kunna hårdkoda ett versionsnummer, men jag är inte ett fan av att hårdkoda någonting. Nedan hittar du ett trevligt knep för att ta för sig av versionsinformationen för jQuery UI som lagras i WordPress.
add_action('wp_enqueue_scripts', function() {
...
$wp_scripts = wp_scripts();
wp_enqueue_style('jquery-ui-css',
'//ajax.googleapis.com/ajax/libs/jqueryui/'. $wp_scripts->registered['jquery-ui-autocomplete']->ver. '/themes/smoothness/jquery-ui.css',
false, null, false
);
});
Vi använder [wp_enqueue_style](https://developer.wordpress.org/reference/functions/wp_enqueue_style/)()för att registrera och lägga till en ny stilmall med den angivna CDN-sökvägen som andra argument. För att hämta ett giltigt versionsnummer för jQuery UI använder vi informationen från funktionen [wp_scripts](https://developer.wordpress.org/reference/functions/wp_scripts/)().
Och det är allt vi behöver för att köa skript!
Skriver Javascript för automatisk komplettering
Låt oss återgå till vår autocomplete.jsfil. Vi vet att när det här skriptet laddas är jQuery och jQuery UI Autocomplete redan inlästa, och vi har även tillgång till en global variabel med nödvändig information. Låt oss börja med att ställa in en jQuery-dokument redo-funktion för att säkerställa att vår kod körs efter att DOM är klart.
jQuery(function($) {
// All code in here
});
Om vi hänvisar till jQuery UI Autocompletes doumentation lär vi oss att vi måste göra en jQuery-väljare som riktar in sig på ett inmatningsfält och köra funktionen autocomplete()på det.
Detta är en punkt där du kan justera koden för att passa dina behov. Den här handledningen kommer att tillämpa autoslutförandet på det vanliga WordPress-sökfältet (som vanligtvis läggs till i tema genom att inkludera sökmallen eller som en widget). Sökinmatningens klassnamn kan variera från tema till tema. Men du kanske vill rikta in dig på ett anpassat inmatningsfält eller söka i en speciell mall. Allt du behöver göra är att ändra jQuery-väljaren så att den riktar sig till den inmatning du vill ha.
I mitt tema har den vanliga WordPress-sökfältsinmatningen en klass av .search-field. Jag lägger också till det överordnade formulärets klassnamn för att ytterligare begränsa det så att vi inte riskerar att autoslutförande tillämpas på något annat med samma klass.
Enligt autokompletteringsdokumentationen kan vi utföra ett AJAX-anrop i fastigheten source(som måste returnera en rad objekt för att visas i autoslutförandet). Vi kommer att använda jQuerys Ajax-funktion för att göra just det:
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);
}
});
},
});
});
På raden #2talar vi om för jQuery UI Autocomplete vilket inmatningsfält vi vill använda autocomplete på. Ändra denna väljare så att den passar dina behov.
I den enklaste formen förväntar sig Autocomplete en array av objektobjekt till sourceegenskapen. Här skapar vi en funktion med två parametrar; requestinnehåller information om vårt inmatade värde (request.term), och responsesom är en återuppringningsfunktion vi behöver för att anropa och tillhandahålla data. Det är vad vi gör i AJAX:s successfunktion vid linje #13.
AJAX-anropet i sig är ganska standard. Vi definierar datatypen som JSON – detta är viktigt annars kommer jQuery UI Autocomplete inte att kunna analysera resultaten. När urlvi kommer åt ajax_urli den globala variabeln lokaliserade vi till vårt skript tidigare; AutocompleteSearch. Och när datavi passerar ett informationsobjekt. Egenskapen actionär obligatorisk och nödvändig för nästa steg – som är att identifiera denna specifika AJAX-förfrågan i PHP. Vi vidarebefordrar också den inmatade termen i ingången och nonce av säkerhetsskäl.
Det är det för sourcesfastigheten. Det finns en annan sak vi behöver lägga till i vårt autoslutförandeskript. Som standard i jQuery UI Autocomplete att välja ett objekt automatiskt fyller inmatningen med det valda elementet. Vi vill omdirigera användaren till inläggets URL när vi väljer ett objekt från listan. Så vi lägger till en funktion till selectegenskapen:
...
success: function(data) {
response(data);
}
});
},
select: function(event, ui) {
window.location.href = ui.item.link;
},
});
});
I den array av objekt vi kommer tillbaka från vårt AJAX-anrop (vi kommer att skriva detta härnäst) är varje objekt ett objekt med egenskaper. Vi kommer att lägga till en anpassad linkegenskap för varje objekt (ui.item) som kommer att innehålla permalänkarna till varje inlägg. Vi skickar denna URL till [window.location.href](https://www.w3schools.com/js/js_window_location.asp)som kommer att utlösa en webbläsaromdirigering.
Och det är allt för Javascript-delen! Allt som återstår är att skriva PHP-delen som lyssnar på AJAX-förfrågningar med åtgärden autocompleteSearch.
Returnerar resultat i PHP till AJAX-förfrågningar
För att skriva funktioner som svarar på specifika AJAX-förfrågningar använder vi krokarna wp_ajax_{action}(inloggade besökare) och wp_ajax_nopriv_{action}(icke-inloggade besökare). Vi definierade åtgärden som autocompleteSearchi vår AJAX-förfrågan ovan. Se mitt inlägg som förklarar hur AJAX fungerar i WordPress om du inte är bekant med detta.
Låt oss ställa in detta i functions.php(eller var du än lägger till din kod i 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();
}
Med ovanstående kod kopplar vi samma funktion till de två AJAX-krokarna. I alla funktioner som är kopplade till wp_ajax AJAX-krokarna måste vi se till att alltid die()eller exiti slutet så att vi inte ekar ut oönskad utdata. Jag använder WordPress- [wp_die](https://developer.wordpress.org/reference/functions/wp_die/)()funktionen.
Vi kan hämta skickad data från Javascript med hjälp av $_REQUEST(fungerar för både GET- och POST-förfrågningar). I vår Javascript-kod passerade vi den inmatade termen i nyckeln ’ term’. Det betyder att vi kan hämta värdet av det i $_REQUEST['term']. Vi kan sedan göra en förfrågan utifrån detta. Kom ihåg att vi bara vill returnera resultat som matchar denna sökterm.
Detta är ytterligare en punkt där du helt kan ändra och justera koden för att passa dina behov. Den här handledningen kommer att utföra en standardfråga på inlägg och sidor, men du kan justera frågan eller utföra en helt annan fråga på olika data. Du kanske föredrar eller behöver utföra en manuell SQL-fråga istället (det är säkert mer minneseffektivt). Den avgörande delen här är arrayen som vi ekar i slutet, som tolkas av vår Javascripts autokompletteringskod.
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();
}
Först kontrollerar vi om nonce var giltig för att skapa viss säkerhet på våra AJAX-samtal. Vi kan göra detta genom att anropa funktionen [check_ajax_referer](https://developer.wordpress.org/reference/functions/check_ajax_referer/)(). Jag har också lagt till kod för att säkerställa att vi inte utför en tung begäran om den returnerade söktermen var tom. Vi bör då returnera en tom json-kodad array.
Exempelkoden ovan utför en [WP_Query](https://developer.wordpress.org/reference/classes/wp_query/)med en sökning på den inmatade termen. Vi måste ställa in posts_per_pagesom -1för att säkerställa att vi ger tillbaka alla matcher. Kolla i dokumentationen WP_Queryom du vill finjustera frågan ytterligare.
Vi går sedan igenom resultaten (line #17) och fyller i en array med matchningar (line #19-23). jQuery UI Autocomplete behöver som minimum värdet labelför att ange vad som ska visas i autocomplete-rutan. Vi skickar även vidare permalänkar i nyckeln ’ link’ som är vad vi använder i vår Javascript-kod för att omdirigera användaren.
Slutligen vid raden #27ekar vi den genererade arrayen som JSON genom att använda [json_encode](https://www.php.net/manual/en/function.json-encode.php)().
Med denna PHP-del på plats borde vår autokomplettering fungera! Uppdatera din webbplats och testa!
Valfria förbättringar
Ett vanligt problem är att antalet matchningar är för många och att autokompletteringsrutan blir för stor. Det finns två lösningar på detta.
En lösning är att lägga till egenskapen minLengthi autocomplete()funktionen i Javascript. Den här egenskapen kommer bara att utlösa rutan för autoslutförande efter att ett visst antal tecken har matats in. Som ett exempel kan vi kräva minst 3 tecken innan autoslutförande utlöses:
...
select: function(event, ui) {
window.location.href = ui.item.link;
},
minLength: 3,
});
});
jQuery UI Autocomplete föreslår en annan lösning här. Den visar ett exempel på att lägga till lite CSS för att lägga till en fast höjd och en intern rullningslist i autokompletteringsrutan.
Slutsats och fullständig kod
Vi har framgångsrikt lagt till ett autoslutförande i WordPresss sökfunktion där vi har full kontroll över de matchningar som ska returneras. Det ger besökarna ett snabbare sätt att navigera i ditt innehåll eftersom att klicka på en matchning omdirigeras direkt till inlägget, snarare än att ta en omväg på en sökresultatsida först. Att implementera ett autoslutförande kanske inte alltid är vettigt på alla WordPress-webbplatser, men det kan vara bra för att söka efter specifikt innehåll eller inom speciella mallar!
Här är den slutliga koden i sin helhet:
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.googleapis.com/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();
}
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;
},
});
});
