Neulich habe ich für die Webseite eines Freundes ein Fotoalbum mit Ruby on Rails entwickelt. Da ich nicht unbedingt die Bilder auf meinem Server haben wollte, lag die Verwendung von Flickr nahe. Für den Zugriff auf Flickr mit Ruby existieren einige Möglichkeiten: flickr ist wohlbekannt durch den Rails Screencast Putting Flickr on Rails, leider wurde das Flickr Interface schon lange nicht mehr weiterentwickelt. Da wollte rflickr in die Bresche springen, jedoch hat sich die Aktivität auch bei rflickr wieder schnell gelegt… Und bei beiden Projekten ist die Dokumentation recht spärlich gesät und erschwert dadurch den Einstieg. Flickrb und Net::Flickr sind zwei weitere Projekte welche ein Flickr Interface für Ruby bauen wollen, jedoch haben beide bis jetzt keine Pakete veröffentlicht und die Aktivität ist bei bei RubyForge auf 0%.
Doch zum Glück hatte der findige Entwickler Hank Lords eine glorreiche Idee: Er machte sich die dynamischen Eigenschaften von Ruby zu nutze und entwickelte mit Flickraw ein Ruby Interface für das REST API von Flickr. Der Clou dabei: Mittels den Reflexion-Methoden getMethods und getMethodInfo erstellt sich das Interface zur Laufzeit selbst. Somit ist Flickraw immer aktuell und braucht auch keine eigene Dokumentation, da es einfach dem aktuellen Flickr API entspricht, und das ist sehr gut dokumentiert. Doch das Einbinden von Flickraw selbst ist für einen Ruby Anfänger nicht gerade intuitiv, und viele Beispiele existieren nicht (und schon gar nicht auf Deutsch) - desshalb ist dieser Artikel entstanden…
Flickraw on Rails
Als Beispiel soll hier ein ganz einfaches Fotoalbum mit Ruby on Rails entstehen. Auf der ersten Seite werden alle Fotosets aufgelistet. Ein Mausklick auf das Fotoset öffnet dieses und zeigt die darin enthaltenen Bilder an. Für die Anzeige wir das bekannt Lightbox JS verwendet, ein “unaufdringliches” JavaScript, welches die Bilder wunderschön hervorhebt indem der Hintergrund abgedunkelt wird und das ganz ohne viel Aufwand für die Integration, da das Verhalten der Elemente getrennt wird von der HTML Deklaration (Es ist nicht immer einfach technische Artikel ohne die präzisen Englischen Ausdrücke zu schreiben - oder wie würde ihr “markup” übersetzten? Auch das oben benutzte Wort Reflexion-Methoden kitzelt den Brechreiz etwas). Als Besipiel werden die Bilder hier im Blog auch dargestellt; siehe ganz unten bei den Bildern von dem Fotoalbums…
Das Herzstück des Fotoalbums ist der FotoController, welcher das FlickRaw Modul einbindet. Der Kontroller liegt wie alle anderen im Verzeichnis app/controllers
class FotosController < ApplicationController
include FlickRaw
api_key = '....'
shared_secret = '....'
user_id = '....'
def index
@photosets = flickr.photosets.getList :user_id => user_id
end
def show
@photos = flickr.photosets.getPhotos(:photoset_id => params[:id]).photo
@photoset = flickr.photosets.getInfo(:photoset_id => params[:id])
end
end
Natürlich müssen die Variabeln api_key, shared_secret und user_id entsprechend angepasst werden:
Als erstes muss man sich bei Flickr anmelden und dann einen neuen Key beantragen. Sobald man den neuen Schlüssel erhalten hat, muss man diesen in die Variable api_key im Kontroller eintragen und dannach wieder in den Browser zurückwechseln und mit dem Link ‘Klicken Sie hier’ unterhalb des API Keys dessen Benutzerauthentifizierung konfigurieren. Auf der nächsten Seite wird dann auch der gemeinsame geheime Schlüssel angezeigt, welcher im Controller in die Variable shared_secret eingetragen werden muss. Als Authentifizierungstyp sollte ‘Desktop Anwendung’ ausgewählt werden, weil dann auch keine Rückruf-URL angeben muss. Die Benutzer ID kann man herausfinden, indem man auf den Link ‘Sie’ im Hauptmenu oben klick und sieht zum Beispiel so aus: ‘94236471@N17′. Hier gibt es mehr Informationen zu den Keys.
Das Modul von Flickraw können wir übrigens mit RubyGems einfach installieren:
gem install flickraw
Die Ressource Foto muss nun in der Konfigurationsdatei routes.rb eingetragen werden:
map.resources :fotos
An sich macht das Beispiel nicht gerade viel von den Möglichkeiten als Ressource Gebrauch, das es nur einen Bruchteil des REST Vokabulars verwendet - daher könnte es eigentlich auch als ganz normalen Kontroller implementiert sein. Ich mag aber einfach die netten RESTful-Helper…
Für die Anzeige müssen nun die HTML Ansichten im Verzeichnis app/views/fotos erstellt werden. Als erstes muss die Indexseite index.html.erb für die Fotosets her. Da ich ein Layout benutze, ist in der entsprechenden Seite nur der Seiteninhalt ohne Kopf- und Fusszeile, Menu, etc. drin.
<h1>Fotoalbum</h1>
<p>Suche Dir unten ein Fotoalbum aus und klicke auf das Bild um die darin enthaltenen Fotos anzuschauen:</p>
<%= render :partial => 'photoset', :collection => @photosets %>
Nun das Partial für die Fotosets _photoset.html.erb:
<div class="photoset">
<h2><%= h(photoset.title) %></h2>
<% if photoset.description %>
<p><%= h(photoset.description) %></p>
<% end %>
<div class="photo">
<%= link_to photoset_image_tag(photoset, :size => :medium, :lightbox => :large), foto_path(photoset.id) %>
<br/><%= h(photoset.photos) %> Fotos
</div>
</div>
Die Methode link_to photoset_image_tag wird im Helper foto-helper.rb definiert, und zwar aufgrund der Definition von Flickr:
module FotoHelper
#
# Returns a flickr image tag for the given photo
#
# size and lightbox paramater could be
#
# :small => 75x75
# :thumbnail => 100px width
# :medium => 240px width
# :large => 500px width
# :original => original width and height
#
def photo_image_tag(photo, options)
link_to(
image_tag(
get_url(photo, photo.id, options[:size]),
get_options(photo, options[:size])),
get_url(photo, photo.id, options[:lightbox]),
{ :rel => 'lightbox[roadtrip]'})
end
#
# Returns a lightboxed flickr image tag for the given photoset
#
# size paramater could be
#
# :small => 75x75
# :thumbnail => 100px width
# :medium => 240px width
# :large => 500px width
# :original => original width and height
#
def photoset_image_tag(photo, options)
image_tag(
get_url(photo, photo.primary, options[:size]),
get_options(photo, options[:size]))
end
private
#
# generates the flickr url
#
def get_url(photo, identifier, size)
sprintf("http://farm%s.static.flickr.com/%s/%s_%s%s.jpg",
photo.farm.to_s, photo.server, identifier, photo.secret,
get_url_size(size))
end
#
# gets the size identifier for the url
#
def get_url_size(size)
case size
when :small
"_s"
when :thumbnail
"_t"
when :medium
"_m"
when :large
""
end
end
#
# Returns the image tag options depending on the choosen size
#
def get_options(photo, size)
options = { :alt => photo.title }
case size
when :small
options['size'] = "75x75"
when :thumbnail
options['width'] = "100"
when :medium
options['width'] = "240"
when :large
options['width'] = "500"
end
return options
end
end
Nun werden die Fotosets angezeigt, fehlen also nur noch die Fotos selber. Diese werden in show.html.erb dargestellt:
<h1><%= @photoset.title %></h1>
<% if @photoset.description %>
<p><%= @photoset.description %></p>
<% end %>
<%= render :partial => 'photo', :collection => @photos %>
<%= link_to "Zurück zur den Fotoalben", fotos_path %>
Auch wird wird wieder ein Partial benötigt, und zwar _photo.html.erb:
<div class="photoset">
<div class="photo">
<%= photo_image_tag(photo, :size => :medium, :lightbox => :large) %>
</div>
</div>
Der Parameter :size definiert die Grösse des Bildes in der Vorschau, währen der Paramter :lightbox die Grösse der Ansicht in Lightbox festlegt. Als Werte können :small, :thumbnail, :medium und :large verwendet werden.
Damit Lightbox seine Dienste verrichtet, muss man es herunterladen, das JavaScript und die Bilder an den entsprechenden Ort im Verzeichnis public kopiert werden, und das JavaScript im Layout inkludiert werden:
<%= javascript_include_tag 'lightbox' %>
Das Resultat ist ein kleines aber feines Fotoalbum. Ich habe bewusst auf eine Blätterfunktion verzichtet, da es so hervorragend in das etwas spezielle Layout passt und man auch mit Lightbox immer durch ein ganzes Fotoset durchklicken kann. Aber mit will_paginate sollte das kein Problem sein…
Die Seite ist leider noch nicht Live da noch andere Bereiche fehlen, wesshalb ich hier keinen Link zum Anschauen des Resultat liefern kann. Dafür hier zwei Bilder wie das fast fertige Fotoalbum aussieht:
Wer Lust hat selber ein Flickt-Fotoalbum in seine Rails Seite einzubinden, der kann hier gleich ein komplettes Rails Projekt zum Ausprobieren und Integrieren herunterladen: Ruby on Rails Flickr Fotoalbum Projekt (221). Einfach die API Keys & Co. anpassen und starten… Viel Spass!

















Kommentare
michi, Blankster, michi, Techi, flöschen
gratis-live-tv.ch, päsi, michi, Manuel, michi [...]
Cris, OMC
jerik, jerik, michi, michi, Simon
Martin Mader, BigBrother, michi, stop, mich [...]