Webkrauts Logo

Webkrauts Webkrauts Schriftzug

- für mehr Qualität im Web

SELECT Bilder FROM Flickr OR PicasaWebAlbums WITH YQL FOR Bildergalerie

SELECT Bilder FROM Flickr OR PicasaWebAlbums WITH YQL FOR Bildergalerie

Was tun, wenn Entwickler Gegner von doppelter Daten- bzw. Bilderhaltung sind, ihnen aber die Zeit fehlt, sich eingehend mit den APIs von Flickr und Picasa Web Albums zu beschäftigen? Michael Grosch zeigt, wie sich mit Hilfe der Yahoo! Query Language (kurz YQL) eine einfache Galerie aus Bildern von Flickr oder Picasa Web Albums erstellen lässt.

Wie arm wäre das Internet ohne Bilder? Doch welche ist die geschickteste Lösung zur Verwaltung von Bildern, um diese auf einer Webseite der Welt zu zeigen? Die Bilderverwaltungen in Content-Management-Systemen sind manchen Kunden zu unübersichtlich. Deshalb bietet sich an, die Verwaltung von Bildern denen zu überlassen, die dies exzellent vormachen, nämlich z.B. Flickr und Picasa Web Albums.

Flickr bietet zwar bereits die Möglichkeit, z.B. ein sog. »Set« als Flash-Diashow einzubinden oder ein »Flickr badge« zu erstellen, doch diese ist nicht sehr flexibel, weshalb wir für den hier beschriebenen Lösungsweg auf die Yahoo! Query Language (YQL) zurückgreifen, um Bilder von Flickr bzw. Picasa Web Albums anzuzeigen.

Vorbereiten: YQL-Abfrage

YQL ist eine Sprache, deren Syntax auf SQL basiert und mit der sich nicht nur Inhalte und Daten von Webseiten, sondern auch unzählige APIs abfragen lassen, ohne sich durch jede einzelne API-Dokumentationen quälen zu müssen. Wer mehr über YQL erfahren möchte und wie diese die Arbeit erleichtert, sollte Christian Heilmanns Artikel »Webinhalte einfach vermischen mit YQL« lesen. Deshalb werden wir hier nicht näher auf die Hintergründe eingehen, die den Rahmen dieses Adventskalendertürchens sprengen würden.

Selbst wenn der Zugriff nicht direkt auf die API von Flickr erfolgt, benötigt ihr mittlerweile, auch für die indirekte Nutzung mit Hilfe von YQL, einen Flickr-API-Schlüssel, den ihr für nicht-kommerzielle Projekte kostenlos beantragen könnt. Die YQL-Abfrage von Bildern innerhalb eines »Sets« bei Flickr sieht entsprechend simpel aus:

  1. SELECT * FROM flickr.photosets.photos({Startbild},{Anzahl der Bilder}) WHERE photoset_id = '{Set-ID}' AND api_key = '{dein Flickr-API-Schlüssel}'

Um die Bilder statt von Flickr von Picasa Web Albums zu holen, sieht die YQL-Abfrage ähnlich aus. Hier ist nur noch zusätzlich die Verwendung einer sog. »open data table« notwendig

  1. USE 'http://www.datatables.org/google/google.picasa.album.photos.xml' AS picasaTable;
  2. SELECT * FROM picasaTable({Startbild},{Anzahl der Bilder}) WHERE user = '{Benutzername}' AND album_key_type='album' AND album_key='{Albumname}';

Testen könnt ihr diese Abfragen über die YQL-Konsole.

Einpacken: PHP-Klasse

Um die Abfragen einfach und fexibel aufzurufen, verpackt ihr diese in eine PHP-Klasse. In der YQL-Dokumentation ist beschrieben, wie ihr diese Abfragen sowie die Verarbeitung der Rückgabe-Werte mit PHP umgesetzen könnt.

  1. class Gallery {
  2.     protected $baseURI = 'http://query.yahooapis.com/v1/public/yql';
  3.  
  4.     const TYPE_FLICKR = 'flickr';
  5.     const TYPE_PICASA = 'picasa';
  6.  
  7.     public function __construct($baseURI = '') {
  8.         if(!empty($baseURI)) {
  9.             $this->setBaseURI($baseURI);
  10.         }
  11.     }
  12.  
  13.     public function getAlbum($service = self::TYPE_FLICKR, $user = 'alaskana', $album = '72157627920494225', $offset = 0, $limit = 12,$thumbnail = '_t', $fullSize = '', $errorMessage = 'Es ist ein unerwarteter Fehler aufgetreten.') {
  14.         switch($service) {
  15.             case self::TYPE_FLICKR:
  16.                 // YQL-Abfrage und daraus resultierende URI für YQL-Webservice erstellen
  17.                 $yqlQuery = "
  18.                    SELECT *
  19.                    FROM flickr.photosets.photos($offset,$limit)
  20.                    WHERE photoset_id='$album'
  21.                        AND api_key='{dein Flickr-API-Schlüssel}'
  22.                ";
  23.                 $yqlQueryURI = $this->getBaseURI() . "?q=" . urlencode($yqlQuery) . "&format=json";
  24.                 $fallbackGalleryURI = 'http://www.flickr.com/photos/' . $user . '/sets/' . $album;
  25.                 break;
  26.             case self::TYPE_PICASA:
  27.                 // YQL-Abfrage und daraus resultierende URI für YQL-Webservice erstellen
  28.                 $yqlQuery = "
  29.                    USE 'http://www.datatables.org/google/google.picasa.album.photos.xml' AS picasaTable;
  30.                    SELECT *
  31.                    FROM picasaTable($offset,$limit)
  32.                    WHERE user='$user'
  33.                        AND album_key_type='album'
  34.                        AND album_key='$album'
  35.                ";
  36.                 $yqlQueryURI = $this->getBaseURI() . "?q=" . urlencode($yqlQuery) . "&format=json";
  37.                 $fallbackGalleryURI = 'https://picasaweb.google.com/' . $user . '/' . $album;
  38.                 break;
  39.         }
  40.  
  41.         // JSON-Daten per cURL holen und in PHP-Objekt umwandeln
  42.         $session = curl_init($yqlQueryURI);
  43.         curl_setopt($session, CURLOPT_RETURNTRANSFER,true);
  44.         $jsonOutput = curl_exec($session);
  45.         $phpObject =  json_decode($jsonOutput);
  46.  
  47.         $output = '';
  48.         if(!is_null($phpObject->query->results)) {
  49.             $output = $this->getHTML($service,$phpObject->query->results,$thumbnail,$fullSize);
  50.         } else {
  51.             $output = '<p class="error">' . $errorMessage . ' (<a href="' . $fallbackGalleryURI . '">Bildergalerie öffnen</a>)</p>';
  52.         }
  53.  
  54.         return $output;
  55.  
  56.     }
  57.  
  58.     protected function getHTML($service,$result,$thumbnail,$fullSize) {
  59.         switch($service) {
  60.             case self::TYPE_FLICKR:
  61.                 return $this->getHTMLForFlickr($result,$thumbnail,$fullSize);
  62.                 break;
  63.             case self::TYPE_PICASA:
  64.                 return $this->getHTMLForPicasa($result,$thumbnail,$fullSize);
  65.                 break;
  66.         }
  67.     }
  68.  
  69.     protected function getHTMLForFlickr($result,$thumbnail,$fullSize) {
  70.         $output = "<ul class=\"yqlGallery\">";
  71.         // Ergebnis parsen und HTML-Code erstellen
  72.         foreach($result->photo as $photo){
  73.             $output .= "<li><a rel=\"galleryItem\" href=\"http://farm" . $photo->farm . ".static.flickr.com/" . $photo->server . "/" . $photo->id . "_" . $photo->secret . $fullSize . ".jpg\" title=\"" . $photo->title . "\"><img src=\"http://farm" . $photo->farm . ".static.flickr.com/" . $photo->server . "/" . $photo->id . "_" . $photo->secret . "" . $thumbnail . ".jpg\" alt=\"" . $photo->title . "\" /></a></li>\n";
  74.         }
  75.         $output .= "</ul>";
  76.         return $output;
  77.     }
  78.  
  79.     protected function getHTMLForPicasa($result,$thumbnail,$fullSize) {
  80.         $output = "<ul class=\"yqlGallery\">";
  81.         // Ergebnis parsen und HTML-Code erstellen
  82.         foreach($result->entry as $photo){
  83.             $thumbnailURL = str_replace('s72','s' . $thumbnail,$photo->group->thumbnail[0]->url);
  84.             $fullSizeURL = str_replace('s72','s' . $fullSize,$photo->group->thumbnail[0]->url);
  85.             if($photo->summary->content) {
  86.                 $photoTitle = $photo->summary->content;
  87.             } elseif($photo->title->content) {
  88.                 $photoTitle = $photo->title->content;
  89.             }
  90.                 $output .= "<li><a rel=\"galleryItem\" href=\"" . $fullSizeURL . "\" title=\"" . $photoTitle . "\"><img src=\"" . $thumbnailURL . "\" alt=\"" . $photoTitle . "\" /></a></li>\n";
  91.         }
  92.         $output .= "</ul>";
  93.         return $output;
  94.     }  
  95.  
  96.     public function getBaseURI() {
  97.         return $this->baseURI;
  98.     }
  99.  
  100.     public function setBaseURI($baseURI) {
  101.         $this->baseURI = $baseURI;
  102.         return $this;
  103.     }
  104. }

Auspacken: Verwendung der PHP-Klasse

Nun müssen wir nur noch mit Hilfe der PHP-Klasse Gallery das neue Objekt gallery instanziieren, die Methode getAlbum aufrufen und fertig ist die Bildergalerie. Die Klasse ist so aufgebaut, dass auch dann eine Galerie angezeigt wird, wenn diese ohne Parameter ($gallery->getAlbum();) verwendet wird. Aber richtig sinnvoll wird die Klasse erst durch der Verwendung entsprechender Parameter, wie die folgenden zwei Beispiele zeigen:

  1. $gallery = new Gallery();
  2. echo $gallery->getAlbum(Gallery::TYPE_PICASA,'migrosch','AlaskaYukonKalender2012',0,12,'75-c','800','YQL macht gerade Pause. Die Galerie findet ihr unter folgendem Link');

Beispiel-Galerie: Flickr

  1. $gallery = new Gallery();
  2. echo $output = $gallery->getAlbum(Gallery::TYPE_PICASA,'migrosch','AlaskaYukonKalender2012',0,12,'75-c','800','YQL macht gerade Pause. Die Galerie findet ihr unter folgendem Link');

Beispiel-Galerie: Picasa

Beispiel-Bildergalerie

Anpassen: Bildgrößen

Auch wenn Flickr sehr populär ist und deshalb zur ersten Wahl zählt, solltet ihr auch Picasa Web Albums, besonders im Hinblick auf die verwendbaren dynamischen Bildgrößen, in Betracht ziehen. Ein Blick auf die Parameter 6 und 7 offenbart diese Flexibilität. Bei Flickr stehen durch Modifikation der Bild-URI »nur« folgende sechs verschieden Größen zur Verfügung (das »?« steht für die sich durch Skalierung auf die angegebene Breite ergebende Höhe):

  • Square (75 x 75): 6309388959_9b12e5a8b5_s.jpg
  • Thumbnail (100 x ?): 6309388959_9b12e5a8b5_t.jpg
  • Small (240 x ?): 6309388959_9b12e5a8b5_m.jpg
  • Medium 500 (500 x ?): 6309388959_9b12e5a8b5.jpg
  • Medium 640 (640 x ?): 6309388959_9b12e5a8b5_z.jpg
  • Large (1024 x ?): 6309388959_9b12e5a8b5_b.jpg

Bei Picasa Web Albums hingegen könnt ihr die Bildgröße frei definieren. Außerdem steht eine Beschneiden-Option zur Verfügung. Durch die Verwendung des Zusatzes "-c" bei den Bildgrößen-Parametern werden die Bilder quadratisch mit der definierten Kantenlänge beschnitten. Dies bietet die nötige Flexibilität, die Galerie an die jeweiligen Projekt-Anforderungen anzupassen.

Probleme beim Auspacken: Fallback

Natürlich bringt die oben beschriebene Lösung eine Abhängigkeit von externen APIs mit sich, die unter Umständen, auch wenn das eher unwahrscheinlich ist, gelegentlich nicht zur Verfügung stehen könnten. Deshalb wird als Fallback ein direkter Link zum jeweiligen Album bei Flickr oder Picasa Web Albums ausgegeben.

Optimieren: Performance

Zur weiteren Optimierung könntet ihr mit Hilfe von HTML5 Local Storage den fertigen HTML-Code der Galerie beim ersten Aufruf im Browser ablegen (siehe Chris Heilmanns Kalendertürchen von 2010 "HTML5 als Geschenkverpackung von Daten"). Dadurch müssen bei den nächsten Aufrufen nicht wieder YQL und indirekt auch die entsprechenden APIs bemüht werden.

Es wäre nicht nur das Internet ärmer ohne Bilder, sondern auch der Web-Entwickler ohne die Möglichkeiten, die ihm YQL bietet. Die Erstellung einer Bildergalerie kratzt hier nur an der Oberfläche. Deshalb kann ich nur empfehlen, euch dieses praktikable Multifunktionswerkzeug, das in keinem Web-Werkzeugkasten fehlen sollte, einmal näher anzuschauen.

Kommentare

Ulf
am 31.12.2011 - 16:45

Hi,

coole Klasse, echt praktikabel.

Gibt es auch eine Lösung für private Alben (bei Flickr)? Denn der GET-Request bekommt dann keine Bilder zurück (verständlich). Kann ich ihm einfach diese Berechtigung "geben", z.b. per zusätzlichen GET-Param (mit API & OAuth etc. pp. funktioniert es bestimmt, dass ist mir aber mit Kanonen auf Spatzen...).

Permanenter Link
Michael Grosch

Michael Grosch (Autor)
am 01.01.2012 - 14:21

Die Frage mit den privaten Alben habe ich mir auch schon gestellt. Allerdings ist mir momentan keine Möglichkeit bekannt, wie man mit YQL private Alben von Flickr abfragen kann.

Permanenter Link

Die Kommentare sind geschlossen.