Implementiamo Google Instant sul nostro sito con MooTools
Ieri Google ha pubblicato il nuovo servizio di ricerca istantanea, chiamato per l’appunto “Google Instant”.
A detta di Google, questo nuovo sistema di ricerca permette di far risparmiare 4 secondi a ricerca, che si traduce in un risparmio globale di 11 ore al secondo.
A questo punto mi è venuto un dubbio: se riesco a risparmiare tempo più velocemente del tempo che scorre, potrò tornare indietro nel tempo come Michael J. Fox?
Non riuscendo a trovare risposta ai miei quesiti (Michael non so perché ma non mi ha convinto) ho deciso di provare a implementare anche io questo sistema di ricerca utilizzando MooTools e le Google Search APIs.
Piano d’Attacco
La ricerca istantanea non è poi così complicata da realizzare tecnicamente, la cosa più impressionante è la velocità con la quale Google è in grado di fornire i risultati, ma visto che anche noi vogliamo utilizzare i server di google, questo non sarà un problema.
Sfogliando la documentazione delle Google AJAX Search API ci si rende conto subito che il sistema proposto nell’Introduction non ci potrà essere d’aiuto. Queste API infatti, pur essendo molto comode, automatizzano troppo il processo, gestendo da sé il form di ricerca. Il nostro obiettivo invece è quello di eseguire una chiamata AJAX ad ogni pressione di un tasto nella input di ricerca. Infatti nell’esempio che mostrerò ho deciso di non inserire neanche il pulsante di submit.
Proseguendo nella lettura della documentazione arriviamo al paragrafo “Flash and other Non-Javascript Environments” e le cose iniziano a farsi interessanti. Qui infatti ci viene offerta la possibilità di fare una chiamata AJAX e di ottenere la lista dei risultati in formato JSON. Tutto OK quindi, o quasi… In realtà non possiamo fare una classica chiamata AJAX perché verremmo subito bloccati dalla same origin policy ovvero un limite di sicurezza imposto dai browser che non consente di fare chiamate AJAX su domini “esterni”.
Poco più in basso nella documentazione però viene in nostro soccorso JSON-P ovvero una particolare chiamata AJAX non vincolata dalla same origin policy che passa il risultato tramite una callback.
Grazie a MooTools questo tipo di chiamata è veramente semplice, infatti in MooTools More è presente la classe Request.JSONP che ci consente di usare questa tecnologia esattamente come una qualsiasi altra normalissima Request AJAX.
Ora che tutti i pezzi del puzzle sono al loro posto…
Implementazione
Ecco la classe che ho prodotto in pochissimo tempo grazie a MooTools e Google:
var InstantSearch = new Class({
Implements: Options,
options: {
lang: 'en',
results: 4,
append: ''
},
initialize: function(options) {
this.setOptions(options);
this.searchInput = document.id(this.options.searchInput);
this.resultsContainer = document.id(this.options.resultsContainer);
this.searchInput.addEvent('keyup', this.updateSearch.bind(this));
},
updateSearch: function() {
if (this.request) this.request.cancel();
this.request = new Request.JSONP({
url: 'http://ajax.googleapis.com/ajax/services/search/web?v=1.0',
method: 'get',
data: {
q: this.searchInput.get('value') + ' ' + this.options.append,
hl: this.options.lang,
rsz: this.options.results
},
onComplete: function(response) {
this.resultsContainer.set('html','');
if (response.responseStatus == 200)
response.responseData.results.each(function(result) {
var resultBlock = new Element('DIV', {'class': 'result'});
new Element('H2', {html: result.title}).inject(resultBlock);
new Element('A', {
html: result.url,
href: result.url,
title: result.titleNoFormatting,
rel: 'external'
}).inject(resultBlock);
new Element('P', {html: result.content}).inject(resultBlock);
resultBlock.inject(this.resultsContainer);
}, this);
}.bind(this)
}).send();
}
});
Alcune informazioni utili: l’indirizzo che ho usato per la richiesta JSONP (http://ajax.googleapis.com/ajax/services/search/web?v=1.0) è privo della chiave d’uso che google consiglia di usare sempre, ma che non è obbligatoria e quindi nel nostro esempio ho ritenuto superflua.
La classe va inizializzata passando obbligatoriamente come parametri una input e un container (un DIV o altro) per l’elenco dei risultati, il resto sarà automatico.
Ci sono inoltre alcune opzioni che è possibile alterare, come:
- lang: permette di cambiare la lingua della ricerca (default: en)
- results: permette di cambiare il numero di risultati restituiti. Google permette dei valori compresi tra 4 e 8 (default: 4)
- append: permette di aggiungere una stringa in fondo alla ricerca inserita dall’utente. In questo modo si può ad esempio limitare i risultati a un particolare sito con “site:miosito.it” o aggiungere sempre un determinato termine
Ci sono altre opzioni che google offre per modificare la ricerca, ma ho preferito mantenere la classe il più semplice possibile per questo articolo.
Vediamola all’opera:
[iframe src=”//jsfiddle.net/KhTv2/1/embedded/”]
La velocità è verramente impressionante a mio avviso, tuttavia senza DeLorean mi sa che il viaggio nel tempo dovrà attendere…
Grande Giove!
hai per caso idea di come si possano effettuare ricerce su google italia con le api di google? perchè di default ricerca su google.com e i risultati non sono uguali!
Il parametro hl della request specifica la lingua dell’applicazione ma non influenza la lingua dei risultati.
Per ottenere quello che ti serve devi aggiungere un paio di parametri che ho omesso per brevità:
– Il parametro “lr” corrisponde alla lingua dei risultati (ovvero: Pagine in Italiano)
– Il parametro “gl” invece specifica la località di provenienza dei risultati (ovvero: Pagine provenienti da Italia)
Puoi quindi sostituire la riga “hl: this.options.lang,” con “hl: this.options.lang, lr: this.options.lang, gl: this.options.lang,”
grazie Massimiliano, ho poi scoperto consultanto la developer guide di google che si dovrebbe usare il parametro gl .. nonostante nei risultati non appare roba che riesco a trovare googlando manualmente. Ultima cosa.. sai se esiste una maniera più elegante per filtrare i contenuti? (invece di inserire site:mywebsite.com inurl: intitle: e via dicendo nella query di ricerca?) .. non mi occorre il codice ma linee guida 🙂 anche perchè sto scrivendo in jQuery non Mootools
a presto,
Giuseppe
Per customizzare al massimo il tipo di ricerca puoi in effetti usare “Google Custom Search Engine”, creando un “engine” personalizzato con i parametri di ricerca (vedi http://code.google.com/intl/en/apis/customsearch/docs/start.html)
A questo punto puoi usare il parametro “cx” e passargli l’id del motore di ricerca o il parametro “cref” con il link all’xml con le specifiche (vedi: http://code.google.com/intl/it-IT/apis/ajaxsearch/documentation/reference.html sotto “Web Search Specific Arguments”)
Non ho provato personalmente ma penso che non dovresti incontrare particolari difficoltà.
Ciao.
ciao scusa dato che io non riesco potresti inserire questo codice per far si che funzioni su questo script: tutorialzine.com/2010/09/google-powered-site-search-ajax-jquery/?
Ciao kevin,
scusa ma non capisco cosa non riesci a fare e che codice vorresti vedere inserito (dove?).
ciao allora mi spiego meglio praticamente io, ho questo script (tutorialzine.com/2010/09/google-powered-site-search-ajax-jquery/?) che è un motore di ricerca con le api di google, e al posto ogni volta di premere “search” vorrei ci fosse google istant ma non so come fare,potresti analizzare lo script e inserire il codice?
Beh kevin, il mio codice di questo articolo non è in jQuery come quello che mi hai linkato ma se lo script che stai usando funziona correttamente ma solo sul click del pulsante “search”, quello che ti manca è di far eseguire lo script sull’evento “keyup” della casella di testo.
In teoria ci dovrebbe essere poco da cambiare.
Ciao.
ciao scusami ma proprio non riesco mi diresti il codice per far eseguire lo script su “keyup”
Prova aggiungendo in script.js:
$(‘#s’).keyup(googleSearch);
ci ho provato ma non è cambiato niente