Un mash-up con Flickr e Slimbox

Questo tutorial non è altro che un condensato di alcuni post, pubblicati in date diverse su questo blog.
In particolare, si tratta dei seguenti post:
Istallare un CMS in locale, del 10 aprile 2008
Come accedere alle API di Flickr con PHP – prima parte, del 15 maggio 2008
Come accedere alle API di Flickr con PHP – seconda parte, del 21 maggio 2008
Come accedere alle API di Flickr con PHP – terza parte, del 24 maggio 2008

Ho pensato di riassumere questi post in un unico articolo, aggiungendo qualche stringa di codice in più, incorporando nello script iniziale le librerie mootools e slimbox. Il codice che andrò a descrivere sarà, pertanto, pressochè identico a quello presentato nei post precedenti, tranne alcune piccole modifiche o aggiunte.

Prima di cominciare a leggere il post, però, consiglio di dare un’occhiata alla demo, giusto per avere un idea di quello che faremo.

Istalliamo il server

Per sviluppare l’applicazione avremo bisogno di un server locale su cui far girare gli script Php.
Il mio consiglio è quello di scaricare XAMPP da Apache Friends. Il pacchetto offre, tra l’altro, Apache, MySQL, PHP, phpMyAdmin. Insomma, tutto quello che serve a far girare i vostri script.

Una volta completata l’istallazione, avviate il pannello di controllo dal menu Programmi/Apache Friends/XAMPP e digitate, nella barra degli indirizzi del vostro browser, http://localhost.

Maggiori info sull’istallazione del server le ho postate qui.

La chiave API

Prima di iniziare a creare lo script, dovete richiedere la chiave API a Flickr. Basta seguire questo link: http://www.flickr.com/services/api/keys/apply/ e chiedere una chiave non commerciale.

Lo script PHP e il metodo flickr.photos.search

Come spiegato nei precedenti post, invieremo una richiesta a Flickr in formato REST, ossia con una semplice URL e una serie di argomenti.
Nei post precedenti, abbiamo invocato il metodo flickr.photos.getInfo, per ottenere una serie di dati relativi ad una singola fotografia. Questa volta, dovendo creare una galleria di immagini, invocheremo il metodo flickr.photos.search, che ci consentirà di ottenere in risposta un array associativo multidimensionale in formato JSON.

Nota: per rendere agevole la comprensione dello script, le variabili PHP che utilizzeremo avranno lo stesso nome degli argomenti del metodo invocato. Nel discorso che segue, quindi, l’argomento ‘tags’ del metodo flickr.photos.search assumerà il valore della variabile $tags. Allo stesso modo, gli argomenti ‘extras’, ‘sort’, size’, ‘page’, ecc., assumeranno i valori delle corrispondenti variabili $extras, $sort, $size, ecc.

Per una lista completa degli argomenti del metodo flickr.photos.search, è sempre bene dare un’occhiata alla documentazione ufficiale, al link flickr.photos.search (sono più di trenta). Qui ci limiteremo a considerare quelli che useremo nella messa in opera della galleria.

Passiamo subito al codice, e assegnamo i valori alle variabili che passeremo come argomenti del metodo:

$api_key = "TUA_CHIAVE_API";
$method = "flickr.photos.search";
$tags = "love";
$extras = 'owner_name,geo';
$sort = 'relevance';
$size = "t";
$per_page = isset($per_page)? $per_page: "9";
$page = strval($_GET['page']);
$page = isset($page)? $page: "1";
$rsp_error = "Errore di connessione: Flickr non risponde. Riprovare in un secondo momento";

La variabile $tags ci fornirà il criterio di ricerca delle fotografie. In pratica, chiederemo a Flickr solo foto etichettate con la parola “love”. Ovviamente, avremmo potuto stabilire molti altri criteri di ricerca, tra cui sono molto interessanti, per le applicazioni che consentono di sviluppare, i criteri geografici. Con $extras passeremo una richiesta di informazioni addizionali. I valori che assegneremo a $extras saranno una serie di parametri separati da virgola. Con questa chiamata chiederemo a Flickr di includere, nella risposta, il nome del proprietario della foto e le coordinate geografiche (se presenti) dove questi ha localizzato l’immagine.

Gli argomenti ‘sort’ e ‘size’ servono ad individuare il criterio di ordinamento delle foto e la dimensione dell’anteprima.

Flickr risponderà alle nostre chiamate restituendoci le foto in insiemi la cui numerosità dipende dall’argomento ‘per_page’. Questo argomento, assieme all’argomento ‘page’, ci consentirà di creare un’impaginazione per la nostra applicazione. Se, alla nostra richiesta, Flickr individuasse 90 foto, potremmo pensare di chiedere 10 pagine di 9 foto ognuna. Basterà assegnare il valore 9 alla variabile $per_page (che stabilisce quante foto ci sono in una pagina) ed un valore compreso tra 1 e 10 alla variabile $page.

Nel nostro esempio, se non è assegnato un valore diverso alle due variabili $page e $per_page, lo script passerà a Flickr i valori 1 per la pagina e 9 per il numero di foto per pagina. Nella nostra applicazione daremo all’utente la possibilità di scorrere le pagine.

Il parametro ‘license’ stabilisce un altro filtro: la licenza d’uso con cui è stata pubblicata la foto. I valori possibili sono i seguenti:

1: Attribution-NonCommercial-ShareAlike
2: Attribution-NonCommercial
3: Attribution-NonCommercial-NoDerivs
4: Attribution License
5: Attribution-ShareAlike
6: Attribution-NoDerivs
7: No known copyright restrictions

Infine, andiamo a stabilire un messaggio di errore da visualizzare all’utente in caso di mancata risposta da parte dei server.

Andiamo ora a creare un array associativo, in cui le coppie chiave => valore sono date dagli argomenti della chiamata, con i rispettivi valori assegnati poco sopra:

$params = array(
 'api_key' => $api_key,
 'method' => $method,
 'tags' => $tags,
 'license' => '2',
 'extras' => $extras,
 'per_page' => $per_page,
 'page' => $page,
 'sort' => $sort,
 'format' => 'php_serial',
);

$encoded_params = array();
foreach ($params as $k => $v){
 $encoded_params[] = urlencode($k).'='.urlencode($v);
}

Una volta che abbiamo l’array di parametri, ne uniamo chiavi e valori, per ottenere un nuovo array numerico $encoded_params(), i cui valori sono dati dalle stringhe ‘argomento=valore’.

Subito dopo costruiamo l’URL e invochiamo l’API:

$url = "http://api.flickr.com/services/rest/?".implode('&', $encoded_params);
$rsp = file_get_contents($url);
if (!$rsp){
 echo "Errore di connessione.";
}else{
 $rsp_obj = unserialize($rsp);
 if ($rsp_obj['stat'] == 'ok'){
  $num_photos = $rsp_obj['photos']['total'];
  $num_pages = $rsp_obj['photos']['pages'];
  $perpage = $rsp_obj['photos']['perpage'];
  $this_page = $rsp_obj['photos']['page'];
  foreach($rsp_obj['photos']['photo'] as $photo){
    //link alla pagina delle foto su flickr
    $photo_page = 'http://www.flickr.com/photos/' . $photo['owner'] . '/' . $photo['id'] . '/';
    //URL dell'icona
    $thumb_src = 'http://farm'.$photo['farm'].'.static.flickr.com/'.$photo['server'].'/'.$photo['id'].'_'.$photo['secret'].'_'.$size.'.jpg';
    //URL della foto
    $photo_link = 'http://farm'.$photo['farm'].'.static.flickr.com/'.$photo['server'].'/'.$photo['id'].'_'.$photo['secret'].'.jpg';
  }
 }
}

A questo punto abbiamo tutti i dati che occorrono a creare la galleria.

La libreria slimbox

Prima, però, dobbiamo scaricare la libreria slimbox e richiamarla nel nostro script.
Cominciate col dare una lettura a http://www.digitalia.be/software/slimbox, giusto per avere un’idea iniziale di slimbox e delle libreria mootools.

Scaricate, poi, la versione che preferite. Personalmente, non ho ancora avuto modi di provare la 1.69. Per questo motivo continuo ad usare la versione 1.57.
Una volta scaricato il pacchetto, leggete il readme.txt e aprite il codice di example.html, per avere un’idea della semplicità con cui potete inserire il codice.

Il pacchetto porta con sè anche la libreria mootools necessaria, quindi non avrete bisogno di ulteriori download. Funzionerà tutto così com’è. Non rimane altro da fare che inserire la libreria all’interno della root del nostro sito (o in un’altra directory, ma senza dimenticare di aggiornare i percorsi dei file nel codice).

Per inserire la libreria nel nostro script, basterà richiamare i due file *.js principali nell’intestazione del documento html, oltre al foglio di stile. A questi, però, ho aggiunto un mio foglio di stile necessario a impaginare la galleria di foto:

<script type="text/javascript" src="js/mootools.js"></script>
<script type="text/javascript" src="js/slimbox.js"></script>
<link rel="stylesheet" href="css/slimbox.css" type="text/css" media="screen" />

<link rel="stylesheet" href="css/digital_a.css" type="text/css" media="screen" />
<!--[if IE]>
<style type="text/css"> ul#gallery li{font-size:118px;height:auto} </style>
<![endif]-->

e inserire l’attributo rel=”lightbox” nel tag <IMG> delle immagini cui desiderate applicare l’effetto slimbox. Se desiderate presentare dei gruppi di immagini, come delle gallerie di foto, allora basterà aggiungere un suffisso a “lightbox”, del tipo:

<a href="images/image-1.jpg" rel="lightbox-atomium">image #1</a>
<a href="images/image-2.jpg" rel="lightbox-atomium">image #2</a>
<a href="images/image-3.jpg" rel="lightbox-atomium">image #3</a>

Inserire slimbox nella galleria

Ora abbiamo tutto quello che occorre. Bisogna solo aggiornare il codice. Eravamo arrivati al ciclo foreach() con cui gestiamo i dati. Rieccolo:

foreach($rsp_obj['photos']['photo'] as $photo){
  //link alla pagina delle foto su flickr
  $photo_page = 'http://www.flickr.com/photos/' . $photo['owner'] . '/' . $photo['id'] . '/';
  //URL dell'icona
  $thumb_src = 'http://farm'.$photo['farm'].'.static.flickr.com/'.$photo['server'].'/'.$photo['id'].'_'.$photo['secret'].'_'.$size.'.jpg';
  //URL della foto
  $photo_link = 'http://farm'.$photo['farm'].'.static.flickr.com/'.$photo['server'].'/'.$photo['id'].'_'.$photo['secret'].'.jpg';
}

Ora bisognerà inserire e impaginare le immagini:

echo "<p>" . $num_photos . " fotografie, con tag <strong>".$tags."</strong>, in " . $num_pages . " pagine (" . $perpage . " per pagina)</p>";
echo "<hr>";
echo "<div id=\"gallery_container\">\n";
echo "<ul id=\"gallery\">\n";

foreach($rsp_obj['photos']['photo'] as $photo){
  $photo_page = 'http://www.flickr.com/photos/' . $photo['owner'] . '/' . $photo['id'] . '/';
  $thumb_src = 'http://farm'.$photo['farm'].'.static.flickr.com/'.$photo['server'].'/'.$photo['id'].'_'.$photo['secret'].'_'.$size.'.jpg';
  $photo_link = 'http://farm'.$photo['farm'].'.static.flickr.com/'.$photo['server'].'/'.$photo['id'].'_'.$photo['secret'].'.jpg';
  echo '<li><a href="'.$photo_link.'" rel="lightbox-myflickr"  title="'.$photo['title'].'&lt;br&gt;Vedi la foto su &lt;a href=&quot;'.$photo_page.'&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;flickr_blue&quot;&gt;Flick&lt;/span&gt;&lt;span class=&quot;flickr_red&quot;&gt;r&lt;/span&gt; &lt;/a&gt; &lt;br&gt;lat: '.$photo['latitude'].', lng: '.$photo['longitude'].'"><img src="'.$thumb_src.'"  title="'.$photo['title'].'" /></a></li>';
  echo "\n\n";
}
echo "</ul>\n";
echo "<div style=\"clear:both\"></div>\n";
echo "<div id=\"gallery_navigation\">\n";
if($this_page > 1){
  echo "<a href=\"".$_SERVER['PHP_SELF']."?page=".($this_page - 1)."\" title=\"Pagina precedente\">Precedente</a>";
}else{
  echo "Precedente";
}
echo " - ".$this_page." - ";
if($this_page < $num_pages){
  echo "<a href=\"".$_SERVER['PHP_SELF']."?page=".($this_page + 1)."\" title=\"Pagina successiva\">Successiva</a>";
}else{
  echo "Successiva";
}
echo "</div>";
echo "</div>";

Abbiamo impaginato le foto riferendoci a questo tutorial di html.it.

Non manca altro che riportare lo script completo:

$api_key = "TUA_CHIAVE_API";
$method = "flickr.photos.search";
$tags = "love";
$extras = 'owner_name,geo';
$sort = 'relevance';
$size = "t";
$per_page = isset($per_page)? $per_page: "9";
$page = strval($_GET['page']);
$page = isset($page)? $page: "1";
$rsp_error = "Errore di connessione: Flickr non risponde. Riprovare in un secondo momento";

$params = array(
 'api_key' => $api_key,
 'method' => $method,
 'tags' => $tags,
 'license' => '2',
 'extras' => $extras,
 'per_page' => $per_page,
 'page' => $page,
 'sort' => $sort,
 'format' => 'php_serial',
);

$encoded_params = array();
foreach ($params as $k => $v){
 $encoded_params[] = urlencode($k).'='.urlencode($v);
}

$url = "http://api.flickr.com/services/rest/?".implode('&', $encoded_params);
$rsp = file_get_contents($url);
if (!$rsp){
 echo "Errore di connessione.";
}else{
 $rsp_obj = unserialize($rsp);
 if ($rsp_obj['stat'] == 'ok'){
  $num_photos = $rsp_obj['photos']['total'];
  $num_pages = $rsp_obj['photos']['pages'];
  $perpage = $rsp_obj['photos']['perpage'];
  $this_page = $rsp_obj['photos']['page'];

  echo "<p>" . $num_photos . " fotografie, con tag <strong>".$tags."</strong>, in " . $num_pages . " pagine (" . $perpage . " per pagina)</p>";
  echo "<hr>";
  echo "<div id=\"gallery_container\">\n";
  echo "<ul id=\"gallery\">\n";

  foreach($rsp_obj['photos']['photo'] as $photo){
    $photo_page = 'http://www.flickr.com/photos/' . $photo['owner'] . '/' . $photo['id'] . '/';
    $thumb_src = 'http://farm'.$photo['farm'].'.static.flickr.com/'.$photo['server'].'/'.$photo['id'].'_'.$photo['secret'].'_'.$size.'.jpg';
    $photo_link = 'http://farm'.$photo['farm'].'.static.flickr.com/'.$photo['server'].'/'.$photo['id'].'_'.$photo['secret'].'.jpg';
    echo '<li><a href="'.$photo_link.'" rel="lightbox-myflickr"  title="'.$photo['title'].'&lt;br&gt;Vedi la foto su &lt;a href=&quot;'.$photo_page.'&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;flickr_blue&quot;&gt;Flick&lt;/span&gt;&lt;span class=&quot;flickr_red&quot;&gt;r&lt;/span&gt; &lt;/a&gt; &lt;br&gt;lat: '.$photo['latitude'].', lng: '.$photo['longitude'].'"><img src="'.$thumb_src.'"  title="'.$photo['title'].'" /></a></li>';
    echo "\n\n";
  }
  echo "</ul>\n";
  echo "<div style=\"clear:both\"></div>\n";
  echo "<div id=\"gallery_navigation\">\n";
  if($this_page > 1){
    echo "<a href=\"".$_SERVER['PHP_SELF']."?page=".($this_page - 1)."\" title=\"Pagina precedente\">Precedente</a>";
  }else{
    echo "Precedente";
  }
  echo " - ".$this_page." - ";
  if($this_page < $num_pages){
    echo "<a href=\"".$_SERVER['PHP_SELF']."?page=".($this_page + 1)."\" title=\"Pagina successiva\">Successiva</a>";
  }else{
    echo "Successiva";
  }
  echo "</div>";
  echo "</div>";

 }
}

Ovviamente, il codice è ridotto all’essenziale. A voi raffinarlo e renderlo più funzionale.
Infine, ecco il foglio di stile digital_a.css:

/* CSS Document */
div#gallery_container{
  float:left;
  width:390px;
  text-align:center;
}
div#gallery_navigation{
  font-family: Arial, Helvetica, sans-serif;
  font-size: .8em;
}
ul#gallery, ul#gallery li{
  margin: 0;
  padding: 0;
  list-style-type: none;
}
ul#gallery{
  float: left;
  width: 390px;
  padding:10px 0 0 10px;
  border:1px solid #000;
  background-color:#222;
}
ul#gallery li{
  float: left;
  width: 118px;
  height: 118px;
  line-height: 118px;
  text-align: center;
  margin: 0 10px 10px 0;
  background-color:#333;
  border:1px solid #AAA;
}
ul#gallery img{
  vertical-align: middle;
}
.flickr_blue{
  color:#3993ff;
}
.flickr_red{
  color:#ff1c92;
}
a img{
  border:1px solid #AAA;
}

Non rimane altro da dire. Per chiarimenti, critiche, opinioni ed eventuali segnalazioni di errori, lasciate un commento a questo post.

Annunci