Google ha sempre favorito la diffusione e la distribuzione dei propri servizi sulle pagine web altrui. Il modulo 'Cerca con Google' è una presenza più che familiare su milioni di siti. Con lo sviluppo crescente di soluzioni basate su Ajax e sul paradigma 'aggiornamento della pagina senza refresh', a Mountain View hanno ben pensato di stare al passo con i tempi. Ecco allora le Google Ajax Search API, un set di componenti e servizi che, come riporta la home page, consente a webmaster e sviluppatori due cose:
- Aggiungere un box di ricerca dinamico sulle proprie pagine con risultati provenienti da Google Web, Video, News, Maps e Blog
- Realizzare applicazioni complesse che sfruttano i servizi di ricerca della stessa Google
Questo articolo è la prima parte di un tutorial che vi guiderà alla scoperta delle potenzialità di questo servizio. Prendremo inizialmente in considerazione le funzionalità di base, per poi concentrarci su quelle avanzate.
Primi passi
Per poter usare le Ajax Search API è innanzitutto necessario ricevere da Google una API Key, ovvero una chiave, un codice, che dà accesso al servizio e consente di sfruttarne le API. Per riceverla bisogna essere però in possesso di un Google Account. Se accedete ad altri servizi Google o usate GMail, lo avete già, altrimenti basta iscriversi e procedere.
Nel modulo di richiesta dalla API Key vi verrà chiesto semplicemente di indicare la URL del sito su cui vorrete usare il box di ricerca in Ajax. Attenzione: la chiave vale e funziona solo all'interno della directory che indicherete e nelle sue sotto-directory. Per esempio, nelle demo che ho preparato per questo articolo la chiave funziona nell'ambito dell'indirizzo http://www.html.it
e delle sotto-directory come https://www.html.it/articoli/2039/
dove si trovano gli esempi. Non funziona, però, su domini come http://blog.html.it
o http://javascript.html.it
. Valutate bene, quindi, dove userete le API prima di richiedere la chiave.
Un altro aspetto fondamentale è che il sito deve essere liberamente accessibile (Google verifica!). Per il resto le API possono essere usate gratuitamente per usi personali e commerciali, a meno che il sito non sia rivolto solo ad utenti paganti.
La procedura per ricevere la chiave è semplicissima. Indicata la URL, basta un click su 'Generate API Key' per essere indirizzati su una pagina come quella mostrata in questo screenshot. Presenta in alto il codice (da copiare, incollare e salvare per gli usi futuri) e in basso il codice di una pagina HTML già pronta per l'uso e configurata per iniziare a sperimentare.
Hello World
Iniziamo subito ad analizzare il primo esempio, che ricalca a grandi linee quello iniziale fornito da Google. Insieme agli altri è disponibile per il download. Un'avvertenza: in essi troverete utilizzata la chiave generata per HTML.it. Se vorrete usarli dovrete ovviamente sostituirla con la vostra. Per comodità, negli snippet di codice che presenterò negli articoli, sarà sostituita dalla sequenza 'abcdef'.
L'esempio mostra il form di ricerca e in basso una serie di risultati provenienti da ricerche sul web, su Google Local, Blog Search, Google Video e Google News. Sono tutti i servizi su cui è possibile effettuare ricerche con le API Ajax. Inoltre, è stata fornita una chiave di ricerca di default (html.it). Passiamo al codice.
Per prima cosa si richiama il CSS di Google, quello che definisce l'aspetto del box:
<link href="http://www.google.com/uds/css/gsearch.css" type="text/css" rel="stylesheet"/>
Subito dopo si inserisce lo script principale, quello a cui va legata la API Key che abbiamo ricevuto:
<script src="http://www.google.com/uds/api?file=uds.js&v=1.0&key=abcdef" type="text/javascript"></script>
La parte principale, però, è quella che segue. Sono le righe di Javascript con cui si inizializza il box di ricerca e si impostano le principali opzioni:
<script type="text/javascript">
function OnLoad() {
// Crea il controllo (box) di ricerca
var searchControl = new GSearchControl();
// Aggiunge i vari tipi di ricerca che si desidera inserire nella pagina
var localSearch = new GlocalSearch();
searchControl.addSearcher(localSearch);
searchControl.addSearcher(new GwebSearch());
searchControl.addSearcher(new GvideoSearch());
searchControl.addSearcher(new GblogSearch());
searchControl.addSearcher(new GnewsSearch());
// Imposta la località iniziale per la ricerca su Google Local
localSearch.setCenterPoint("Roma, Italia");
// Individua l'elemento in cui inserire il box di ricerca
searchControl.draw(document.getElementById("boxricerca"));
// Specifica il termine da usare di default
searchControl.execute("HTML.it");
}
</script>
All'interno della funzione OnLoad
, si crea innanzitutto l'oggetto principale usato dalle API, GSearchControl
, qui assegnato alla variabile searchControl
.
Subito dopo stabiliamo quali tipi di ricerca includere. Per la ricerca locale è possibile impostare anche una località predefinita. Come si vede la sintassi è piuttosto semplice. Tramite il metodo addSearcher()
si aggiungono al controllo principale gli oggetti corrispondenti ai diversi servizi di ricerca: GlocalSearch, GwebSearch, GvideoSearch, GblogSearch e GnewsSearch.
A questo punto, con il metodo draw()
, si stabilisce dove inserire il box, specificando l'id dell'elemento (nell'esempio un div con id="boxricerca"
).
Si chiude con la riga attraverso cui impostare, eventualmente, una chiave di ricerca predefinita. Se si desidera avere un modulo vuoto (come vedremo), basterà lasciare i soli apici, vuoti, senza alcun valore.
Nella parte HTML della pagina troviamo solo due cose cruciali:
- al tag
<body>
va aggiunta la chiamata alla funzioneOnLoad
:<body onload="OnLoad()">
- nel corpo va definito un div vuoto con
id="boxricerca"
:<div id="boxricerca"></div>
Rivediamo l'esempio.
Interfaccia a tab
Il controllo GSearchControl
prevede due modalità di visualizzazione. Quella predefinita è la LINEAR, già vista nel primo esempio. Si può sostituirla con una a tab. È quello che abbiamo fatto nel secondo esempio. Differisce dal primo anche perché restituisce risultati solo dal web, dalle news e dai blog, e perché non ha una chiave di ricerca predefinita. Ecco il codice:
<script type="text/javascript">
function OnLoad() {
// Crea il controllo (box) di ricerca
var searchControl = new GSearchControl();
// Aggiunge i vari tipi di ricerca che si desidera inserire nella pagina
searchControl.addSearcher(new GwebSearch());
searchControl.addSearcher(new GblogSearch());
searchControl.addSearcher(new GnewsSearch());
// Individua l'elemento in cui inserire il box di ricerca e imposta la visualizzazione a tab
var drawOptions = new GdrawOptions();
drawOptions.setDrawMode(GSearchControl.DRAW_MODE_TABBED);
searchControl.draw(document.getElementById("boxricerca"), drawOptions);
// Specifica il termine da usare di default
searchControl.execute("");
}
</script>
Oltre all'assenza della chiave predefinita (si osservi searchControl.execute("");
), la differenza sostanziale risiede in queste righe:
var drawOptions = new GdrawOptions();
drawOptions.setDrawMode(GSearchControl.DRAW_MODE_TABBED);
searchControl.draw(document.getElementById("boxricerca"), drawOptions);
In pratica, piuttosto che limitarci ad accettare le impostazioni di default per il metodo draw()
, siamo intervenuti con l'aggiunta di altre opzioni. La definizione di tali opzioni avviene tramite l'oggetto GdrawOptions()
e il suo metodo setDrawMode()
. È lì che bisogna definire l'opzione GSearchControl.DRAW_MODE_TABBED
per ottenere l'interfaccia con le tab. L'alternativa è GSearchControl.DRAW_MODE_LINEAR
.
Con il metodo draw()
già visto in precedenza si inserisce il box nel div con id="boxricerca"
, ma questa volta si accompagna la dichiarazione con l'indicazione delle opzioni di visualizzazione.
Espandere o chiudere?
Con il terzo esempio lavoreremo sulle modalità di visualizzazione dei singoli moduli di ricerca. In particolare, è possibile far comparire i risultati in tre modi diversi:
GsearchControl.EXPAND_MODE_OPEN
: mostra tutti i risultati;GsearchControl.EXPAND_MODE_CLOSED
: nasconde i risultati;GsearchControl.EXPAND_MODE_PARTIAL
: mostra solo alcuni risultati.
Ecco il codice:
<script type="text/javascript">
function OnLoad() {
// Crea il controllo (box) di ricerca e lo assegna alla variabile searchControl
var searchControl = new GSearchControl();
// Aggiunge i vari tipi di ricerca che si desidera inserire nella pagina e specifica le opzioni sulla modalità di espansione
options = new GsearcherOptions();
options.setExpandMode(GSearchControl.EXPAND_MODE_CLOSED);
searchControl.addSearcher(new GwebSearch(), options);
options = new GsearcherOptions();
options.setExpandMode(GSearchControl.EXPAND_MODE_OPEN);
searchControl.addSearcher(new GnewsSearch(), options);
options = new GsearcherOptions();
options.setExpandMode(GSearchControl.EXPAND_MODE_PARTIAL);
searchControl.addSearcher(new GblogSearch(), options);
// Individua l'elemento in cui inserire il box di ricerca e imposta la visualizzazione LINEAR
var drawOptions = new GdrawOptions();
drawOptions.setDrawMode(GSearchControl.DRAW_MODE_LINEAR);
searchControl.draw(document.getElementById("boxricerca"), drawOptions);
// Specifica il termine da usare di default
searchControl.execute("javascript");
}
</script>
Per ciascuno dei tre moduli abbiamo impostato un'opzione diversa. Si noti anche che siamo tornati all'interfaccia LINEAR e che abbiamo scelto la chiave 'javascript' come quella predefinita.
Nell'esempio 4 mostriamo cosa accade se per tutti i moduli si usa l'opzione CLOSED.
Separare il form dai risultati
Uno dei punti di forza di queste API è senz'altro l'ampia flessibilità che offrono. Come esempio finale vedremo come sia possibile separare nel layout il campo di ricerca dai risultati. Passiamo subito al codice (per il layout abbiamo attinto ad uno dei template di Layoutgala):
<script type="text/javascript">
function OnLoad() {
// Crea il controllo (box) di ricerca e lo assegna alla variabile searchControl
var searchControl = new GSearchControl();
// Aggiunge i vari tipi di ricerca che si desidera inserire nella pagina e specifica le opzioni sulla modalità di espansione
options = new GsearcherOptions();
options.setExpandMode(GSearchControl.EXPAND_MODE_OPEN);
searchControl.addSearcher(new GwebSearch(), options);
options = new GsearcherOptions();
options.setExpandMode(GSearchControl.EXPAND_MODE_OPEN);
searchControl.addSearcher(new GnewsSearch(), options);
options = new GsearcherOptions();
options.setExpandMode(GSearchControl.EXPAND_MODE_OPEN);
searchControl.addSearcher(new GblogSearch(), options);
//Imposta la visualizzazione LINEAR
var drawOptions = new GdrawOptions();
drawOptions.setDrawMode(GSearchControl.DRAW_MODE_LINEAR);
// Indica dove inserire il form di ricerca
drawOptions.setSearchFormRoot(document.getElementById("searchForm"));
// Indica l'elemento in cui inserire i risultati
searchControl.draw(document.getElementById("boxricerca"), drawOptions);
// Specifica il termine da usare di default
searchControl.execute("");
}
</script>
Non differisce molto da quelli già visti, se non in una riga:
drawOptions.setSearchFormRoot(document.getElementById("searchForm"));
È il metodo setSearchFormRoot()
a consentire la magia. Il form verrà inserito all'interno del div con id="searchForm"
, che nella parte HTML abbiamo piazzato nella colonna sinistra.
Abbiamo visto nella prima parte come creare un box di ricerca dinamico sfruttando le API Ajax di Google nelle loro opzioni di base. Vedremo ora un paio di applicazioni pratiche, non prima di segnalare che una collezione di esempi
è stata messa a punto dal team di sviluppo della stessa Google. È un ottimo punto di partenza e ispirazione per adattare alle proprie esigenze
la potenza di questo servizio.
Un motore per il proprio sito
Iniziamo con la creazione di un box con cui effettuare ricerche all'interno di un solo sito. Ecco l'esempio (la ricerca viene effettuata all'interno del blog di HTML.it).
Se avete seguito la prima parte, vi accorgerete che le modifiche da apportare agli schemi di base sono davvero minime. Subito il codice:
function OnLoad() {
// Crea il controllo (box) di ricerca e lo assegna alla variabile searchControl
var searchControl = new GSearchControl();
// Specifica le opzioni sulla modalità di espansione e sul numero di risultati restituiti
var options = new GsearcherOptions();
options.setExpandMode(GSearchControl.EXPAND_MODE_OPEN);
// Imposta il tipo di ricerca e aggiunge i parametri per restringere la ricerca ad un solo sito
var siteSearch = new GwebSearch();
siteSearch.setUserDefinedLabel("Ricerca nel sito htpp://blog.html.it:");
siteSearch.setSiteRestriction("http://blog.html.it");
searchControl.addSearcher(siteSearch, options);
// Individua l'elemento in cui inserire il box di ricerca e imposta la visualizzazione LINEAR
var drawOptions = new GdrawOptions();
drawOptions.setDrawMode(GSearchControl.DRAW_MODE_LINEAR);
searchControl.draw(document.getElementById("boxricerca"), drawOptions);
// Specifica il termine da usare di default
searchControl.execute("");
}
Rispetto a quanto già visto, c'è una sola sezione dello script da esaminare:
var siteSearch = new GwebSearch();
siteSearch.setUserDefinedLabel("Ricerca nel sito htpp://blog.html.it:");
siteSearch.setSiteRestriction("http://blog.html.it");
searchControl.addSearcher(siteSearch, options);
Creato un nuovo tipo di ricerca che opera solo sui siti web (new GwebSearch
), abbiamo impostato due opzioni:
- con il metodo
setUserDefinedLabel
definiamo un titolo, un'etichetta che specifica il tipo di ricerca effettuato; - con il metodo
setSiteRestriction
suggeriamo a Google di restringere la ricerca al sito specificato.
Ulteriori suggerimenti per la personalizzazione e per l'integrazione con Google Coop sono disponibili nella pagina di documentazione delle API.
Un esempio con le mappe
Nell'ultimo esempio vedremo come integrare le API Ajax con le mappe di Google. La demo si presta ad un preciso scenario d'uso. Mettiamo che stiate organizando un congresso da svolgere al Palazzo dei Congressi di Roma. Creerete una pagina per chi arriva da fuori fornendo le solite indicazioni su come arrivare e una mappa che ha come punto centrale il Palazzo dei Congressi. Aggiungerete poi un paio di 'link' per ricercare e visualizzare sulla mappa alberghi e ristoranti situati nelle vicinanze del Palazzo dei Congressi.
Vediamo come si fa.
Per prima cosa sarà necessario inserire nella pagina, oltre allo script per le API Ajax di cui abbiamo parlato nella prima parte, anche quelli per la gestione delle mappe e delle loro API. Vi ricordo anche che per comodità la API key è stata ridotta al valore 'abcde' e che nelle vostre applicazioni dovrete sostituire questo valore con quello della chiave che avrete ottenuto da Google:
<script src="http://www.google.com/uds/api?file=uds.js&v=1.0&key=abcde" type="text/javascript"></script>
<script src="http://maps.google.com/maps?file=api&v=2&key=abcde" type="text/javascript"></script>
<script src="http://www.google.com/uds/solutions/mapsearch/gsmapsearch.js" type="text/javascript"></script>
Subito dopo impostiamo lo script di inizializzazione:
<script type="text/javascript">
function OnLoad() {
// definisce una collezione (array) degli elementi che attivano gli hotspot con la query
var listaHotspot = [
{ element : document.getElementById("hs1"), query : "alberghi" },
{ element : document.getElementById("hs2"), query : "ristoranti" }
];
// imposta le opzioni relative al punto centrale e iniziale della mappa
var options = {
// nome che compare nel tooltip
title : "Palazzo dei Congressi",
// URL del sito Web
url : "http://www.palazzocongressi.it/",
// stabilisce quali sono gli hotspot da collegare alla mappa (il riferimento è all'array definito sopra
hotspots : listaHotspot,
// imposta il livello di zoom della mappa iniziale, adeguandolo a quello della mappa attiva
idleMapZoom : GSmapSearchControl.ACTIVE_MAP_ZOOM
}
// imposta le opzioni del controllo mappa (elemento in cui compare, indirizzo iniziale, opzioni definite sopra)
new GSmapSearchControl(
document.getElementById("mappa"),
"Palazzo dei Congressi, Piazza John Fitzgerald Kennedy, Roma",
options
);
}
</script>
Per prima cosa andiamo a creare un array. Contiene una lista di elementi HTML identificati con il loro id (hs1, hs2
) e per ciascuno una query da sottoporre al motore di ricerca. Si tratta, come si vede, degli alberghi e ristoranti di cui si parlava prima.
Subito dopo impostiamo le opzioni per la visualizzazione delle informazioni relative al punto centrale della nostra mappa (il Palazzo dei Congressi di Roma). Chi ha usato almeno una volta le mappe di Google sa che queste informazioni sono visualizzate all'interno del tooltip attivato con il click sull'icona di localizzazione. I commenti al codice (presenti anche negli esempi da scaricare) chiariscono la funzione di ciascuna opzione.
Vale la pena soffermarsi un attimo sull'ultima. Di default, in questo tipo di applicazione, Google fornisce una mappa iniziale che ha al centro il nostro punto di riferimento e una mappa che si attiva quando si effettua una ricerca. Nel primo caso si parla di mappa in stato 'idle', nel secondo di mappa in stato 'active'. Sempre di default, il livello di zoom per le mappe in stato 'idle' è meno dettagliato di quello in stato 'active'. Con l'istruzione idleMapZoom : GSmapSearchControl.ACTIVE_MAP_ZOOM
non facciamo altro che impostare il livello di zoom della cartina idle come quello della cartina active. Senza questo intervento, il risultato sarebbe questo.
Con l'ultimo blocco di codice stabiliamo dove inserire, nella pagina, la mappa (sarà all'interno del div con id="mappa"
). Quindi l'indirizzo iniziale (che è quello del Palazzo dei Congressi di Roma). Per finire, accodiamo le opzioni definite in precedenza.
Per il Javascript è tutto. Nella sezione <head>
vanno pure definite una serie di regole di presentazione.
Innanzitutto, inseriamo i due CSS forniti da Google:
<link href="http://www.google.com/uds/css/gsearch.css" type="text/css" rel="stylesheet"/>
<link href="http://www.google.com/uds/solutions/mapsearch/gsmapsearch.css" rel="stylesheet" type="text/css"/>
Quindi aggiungiamo un po' di regole ad hoc:
/* imposta l'aspetto del div in cui inseriamo la mappa */
#mappa {
width : 400px;
margin-left: 10px;
padding: 4px;
border : 1px solid black;
}
/* imposta il cursore a manina per i list item con classe hotspot */
li.hotspot {cursor : pointer;}
/* imposta l'aspetto dei list item con classe hotspot in stato :hover */
li.hotspot:hover {color : red;
text-decoration : underline;
}
/* imposta l'altezza iniziale della mappa */
#mappa .gsmsc-idleMapDiv {height : 400px;}
/* imposta l'altezza della mappa quando si effettua una ricerca */
#mappa .gsmsc-mapDiv {height : 400px;}
Anche in questo caso i commenti chiariscono bene la funzione di ciascun blocco.
Concludiamo con l'HTML. A livello del tag <body>
compare al solito l'onload
:
<body onload="OnLoad()">
Segue il div con id="mappa" in cui inseriremo la cartina di Google:
<div id="mappa">Caricamento in corso...</div>
Si chiude con una lista (ul
) i cui item sono rappresentati dalle opzioni per la ricerca di alberghi e ristoranti (i cosiddetti hotspot). A ciascun item assegneremo un id che sia corrispondente a quanto impostato nell'array (hs1, hs2
) e una classe 'hotspot':
<ul>
<li id="hs1" class="hotspot">Alberghi</li>
<li id="hs2" class="hotspot">Ristoranti</li>
</ul>
Anche per questo tipo di applicazione non posso che rimandarvi alla pagina di documentazione, dove potrete trarre spunti per ulteriori approfondimenti su un servizio che qui abbiamo presentato solo nei suoi aspetti essenziali.
Il codice degli esempi è disponibile per il download.