Facebook
Twitter
Google+
Kommentare
6

Tobias Zeisings Selfoss

Früher hatte ich mal den Aufruf gestartet, dass jeder, der ein eigenes Projekt hat und regelmäßig phphatesme ließt doch gerne seine Produkte hier vorstellen darf. Tobias Zeising ist dem Aufruf bereits ein zweites Mal gefolgt und stellt heute sein selfoss vor. Viel Spaß damit.

Ob Facebook, Google+ oder Twitter: alle verwenden als zentrales Element einen Stream, eine Pinnwand oder einen Newsbereich mit den aktuellsten Meldungen. Egal wie man es nennt, es handelt sich dabei immer um die erste Anlaufstelle über die sich der Benutzer über aktuelle Themen informieren kann, einen Überblick bekommt und mit wenigen Blicken weiß, was los ist. Ein Konzept, das so simpel wie nützlich ist. Nur ist das immer begrenzt auf die jeweilige Plattform und am Ende muss man sich durch die verschiedenen Netzwerke und Anwendungen klicken. Das schöne Prinzip vom einzelnen Informationsstrom ist damit dahin.

Nachdem ich schon länger einige interessante Frameworks und Bibliotheken testen wollte, war das für mich Grund genug eine Webanwendung zu bauen, welche aus den verschiedensten Quellen Informationen abgreift und in einem einzelnen Stream präsentiert. Praktisch ein beständiger Fluss an Informationen, weshalb ich die Anwendung nach dem schönen isländischen Wasserfall Selfoss benannt habe. Ein Bild das sehr gut passt, denn der Selfoss besteht aus zahlreichen kleinen Wasserfällen, also sozusagen aus viele einzelnen Informationsströme, die zusammen doch in einem Fluss münden. Genau so sollte das Programm funktionieren: Beliebige Quellen können als Plugins (ich habe sie spouts getauft) eingehängt werden und den Informationsstrom so mit Meldungen aus beliebigen Quellen (RSS Feeds, Twitter, Log Files, usw.) befüllen.

Requirements & Planung

Ich habe schon einige Erfahrung mit meinem letzten Projekt, dem RSS Reader rsslounge sammeln können und somit eine ganze Reihe an Anforderungen:

  • Der Aufbau des Programms sollte simpel sein. Keine riesigen generischen Schnittstellen, keine fetten Frameworks und auch nicht die Möglichkeit alles abdecken zu können. Eine schlichte Architektur und einfacher Code sollten im Zentrum stehen.
  • Ein einfaches Framework mit möglichst wenigen Dateien sollte verwendet werden. Bei rsslounge setze ich auf das Zend Framework und bin damit auch sehr zufrieden. Allerdings ist das ZF sehr umfangreich und somit wird ein Update auf eine neue Version sehr lästig, da sich sehr viele Dateien sich über FTP durch die Leitung quälen müssen.
  • Leichte Erweiterbarkeit durch zusätzliche Datenquellen (Spouts).
  • Selfoss sollte auf dem iPad und auf Android laufen.
  • Selfoss sollte von seinem Einsatzgebiet nicht zu sehr eingegrenzt werden. Man kann das Programm also als zentrale Sammelstelle für Informationen nutzen, aber auch als mashup Tool verwenden. So kann Selfoss Informationen sammeln und als RSS Feed wieder zur Verfügung stellen. Oder man setzt Selfoss als Livestream ein und präsentiert Meldungen, die man selbst auf verschiedene Plattformen veröffentlicht hat, an einer zentralen Stelle.

Das MVC Pattern als Grundgerüst hat sich gut bewährt und ist mittlerweile auch zum letzten Entwickler durchgedrungen. Für das Anbinden der Spouts hatte ich bereits bei rsslounge einen ähnlichen Mechanismus entwickelt. Der sollte wieder recycelt und in abgewandelter Form eingesetzt werden.

Fat Free PHP Framework

Als Basis-Framework habe ich mich für das Fat Free PHP Framework entschieden. Dabei handelt es sich um ein sehr schlankes Framework, das mit einer Größe von 55kb beworben wird, tatsächlich dann aber doch 223kb und 27 Dateien umfasst. Im Vergleich zum Zend Framework aber immernoch super schlank.

Das Fat Free PHP Framework (kurz F3) benötigt auch PHP 5.3, da es die neuen Möglichkeiten, wie beispielsweise Lambda Funktionen verwendet. Für mich perfekt, die Sprachfeatures von PHP 5.3 mal vol auszuschöpfen. F3 bringt dabei alle wichtigen Funktionen mit, die man so benötigt:

  • Routing Mechanismus (sehr einfach auch im MVC Style realisierbar)
  • Datenbankzugriff (sogar mit einem mini ORM und einem MongoDB mapper)
  • Template Engine
  • Schnick Schnack wie: On-the-fly JavaScript/CSS compressor, CAPTCHA generator, OpenID, usw.

Was mich neben der kompakten Größe überzeugt hat, sind die einfachen Programmkonstrukte, die sich damit ergeben. Am besten sieht man das an einem Beispiel:

require __DIR__.'/libs/f3/base.php';

F3::set('AUTOLOAD','libs/f3/|libs/|libs/WideImage/|models/|libs/twitteroauth|libs/FeedWriter');

F3::route('GET /', 'controllers\Index->home');

F3::route('GET /mark/@item', 'controllers\Items->mark');

F3::route('POST /source', 'controllers\Sources->add');

F3::route('PUT /source/@id', 'controllers\Sources->write');

F3::run();

Hier wird als erstes das F3 Framework eingebunden. Dann werden die Verzeichnisse für das Autoloading gesetzt. Anschließend werden die Routen definiert. Da das F3 Framework grundsätzlich den REST Ansatz unterstützt, wird mit F3::route die HTTP Methode und die Ziel URL festgelegt. In einem zweiten Parameter steht dann die Klasse und Methode, die aufgerufen wird (z.B. in der Klasse \controllers\Index die Methode home). Man könnte auch direkt eine Funktion übergeben:

F3::route('GET /about',

function() {

echo 'No subliminal messages here...';

}

);

Wie die gesamte Initialisierung von Selfoss und die Definition der Routen erfolgt, könnt ihr euch hier ansehen: https://github.com/SSilence/selfoss/blob/master/index.php

Das Backend im Überblick

Was passiert noch im PHP Backend von Selfoss? Eine ganze Menge, aber dann doch mit erstaunlich wenig Code und eben simpel gestrickt.

Da mich die Templating Engine von F3 nicht überzeugen konnte und ich die PHP Programmierkonstrukte für ein Templating für ausreichend halte, habe ich mir selbst eine Hilfsklasse für das Rendern der PHP Templates erstellt: helpers/View.php. Die Klasse bietet die Methode render, welche einfach das übergebene Template einbindet, ausführt und als String zurück gibt. Es unterstützt auch eine JSON Ausgabe und bietet ein paar Hilfsfunktionen. Damit können Views wie im Zend Framework genutzt werden.

Ein ordentlicher Logger hat mir auch im F3 Framework gefehlt. Also habe ich einen ganz einfachen Logger erstellt: helpers/Logger.php, der ausschließlich in Dateien loggen kann.

Für den Datenbankzugriff wird die F3 Komponente verwendet. Die funktioniert auch sehr einfach. Hier ein Beispiel für einen MySQL Datenbankzugriff:

F3::set('DB',

new DB(

'mysql:host=localhost;port=3306;dbname=mysqldb',

'admin',

'p455w0rD'

)

);

DB::sql('SELECT brandName FROM wherever');

foreach (F3::get('DB->result') as $row) {

// whatever you want to do with $row

}

Neben MySQL wird aber auch Sqlite und MongoDB unterstützt. Zwei Modelklassen für die vom Benutzer definierte Quellen und eine für die Einträge kapseln sämtliche Datenbankzugriffe (siehe models).

Bibliotheken Backend

Ich bin nicht zimperlich, was den Einsatz von Bibliotheken angeht. Selber machen ist ganz nett, aber es gibt mittlerweile super OpenSource Libraries, die einfach hervorragend sind. Also habe ich auch hier wieder meine Bookmarks gewälzt und auf folgende Bibliotheken zurückgegriffen:

  • SimplePie: Verwende ich zum Parsen von RSS Feeds. Eine spitzen Bibliothek, die auch mit fehlerhaften Feeds ganz gut umgehen kann.
  • WideImage: Verwende ich zum Erstellen der Vorschaubildchen.
  • htmLawed: Damit bereinige ich die Feed Einträge von schädlichen HTML und JavaScript Code. Das ist nicht nur aus Sicherheitsaspekten sinnvoll, sondern häufig wird auch fehlerhafter HTML Code ausgeliefert.
  • jsmin: F3 besitzt zwar einen JavaScript Minifier. Der hat bei mir aber nicht funktioniert und somit setze ich auf diese Lib, die ich auch schon seit langem in rsslounge verwende
  • cssmin: das Gleiche wie jsmin für CSS Dateien
  • PHP Universal Feed Generator: Damit erzeuge ich ein neues RSS Feed aus den gesammelten Beiträgen.
  • floIcon: Damit werden ICO Dateien verarbeitet

Spouts

Wie eigene Datenquellen ergänzt werden können, ist in der Dokumentation zu finden. Wer z.B. irgendeine Datenquelle (z.B. Logfiles, Email Account, Webseite ohne RSS) anzapfen will, muss dazu lediglich eine einzelne PHP Klasse implementieren. Eine Anleitung, wie das geht, findet ihr in meinem Blog.

Im Prinzip funktioniert die Anbindung wie folgt:

  • Die Hilfsklasse ContentLoader.php lädt alle abzurufenden Quellen, die der Benutzer konfiguriert hat, aus der Datenbank
  • Dann wird zu jeder einzelnen Quelle das dazugehörige Spout geladen (das macht die Hilfsklasse SpoutLoader.php mit Hilfe von Reflection). Einen solchen Spout könnt ihr einfach implementieren, ohne Selfoss genauer zu kennen.
  • Der ContentLoader ruft die load Methode des jeweiligen Spouts auf, welche dann die Inhalte (z.B. via RSS) abruft.
  • Dann holt sich der ContentLoader nacheinander alle abgerufenen Beiträge und speichert diese in der Datenbank ab (sofern noch nicht vorhanden).

Frontend

Für das HTML Grundgerüst konnte ich endlich einmal die HTML5 Boilerplate Vorlage ausprobieren. HTML5 war für mich die Technik der Wahl, nachdem alles auch auf mobilen Plattformen laufen sollte. Im Grunde verwende ich nichts von den HTML5 Neuerungen, aber wer weiß, was die Zukunft bringt.

HTML5 Boilerplate enthält auch die JavaScript Bibliothek modernizr. Diese prüft das vorhandene System und fügt zum html Tag CSS Klassen hinzu, welche unterstützte Features markieren. So kann sehr einfach geprüft werden, ob z.B. das aktuelle Device touch-Funktionen unterstützt:

if($(‘html‘).hasClass(‘touch‘)) {

…

Frontend Bibliotheken

Nein, ich bin ganz sicher nicht zimperlich was Bibliotheken angeht. Aber wieso das Rad neu erfinden? Hier die Liste mit Bibliotheken, die ich für das Frontend verwende und auch weiterempfehlen kann:

  • Elastic CSS Framework: Mit Browserkompatibilität kann man Nächte verbringen. Gerade was mehrspalitge Layouts usw. angeht. Daher verwende ich Elastics, dass sehr viel out of the box mit bringt.
  • iScroll: Der Stream ist in einem div Element untergebracht. Um das via touch scrollbar zu machen (z.B. auf dem iPad), verwende ich die JavaScript Bibliothek iScroll. Ein echter Tipp, denn diesbezüglich scheint es keine weiteren Alternativen zu geben.
  • jQuery: Muss ich noch was dazu sagen?
  • Keyboard Shortcuts: Ein sehr schönes Skript um ganz einfach mit Funktionen auf Keypress Aktionen zu reagieren.

Download

Selfoss ist natürlich OpenSource (GPLv3) und kann frei heruntergeladen werden:

http://selfoss.aditu.de/

Sämtliche Quellen können auch auf github eingesehen werden.

Gerne könnt ihr mich für Fragen kontaktieren: tobias.zeising@aditu.de. Und wenn jemand eine eigene nützliche Datenquelle (Spout) entwickelt hat, freue ich mich sehr über Feedback und Sourcecode.

Über den Autor

Nils Langner

Nils Langner ist der Gründer von "the web hates me" und auch der Hauptautor. Im wahren Leben leitet er das Qualitätsmanagementteam im Gruner+Jahr-Digitalbereich und ist somit für Seiten wie stern.de, eltern.de und gala.de aus Qualitätssicht verantwortlich. Nils schreibt seit den Anfängen von phphatesme, welches er ebenfalls gegründet hat, nicht nur für diverse Blogs, sondern auch für Fachmagazine, wie das PHP Magazin, die t3n, die c't oder die iX. Nebenbei ist er noch ein gern gesehener Sprecher auf Konferenzen. Herr Langner schreibt die Texte über sich gerne in der dritten Form.
Kommentare

6 Comments

  1. Also bis ich mich komplett durch den Code gewühlt habe schonmal ein großes Lob von mir, sieht wirklich toll aus. Auch das Framework sieht interessant aus.

    Reply

Leave a Comment.

Link erfolgreich vorgeschlagen.

Vielen Dank, dass du einen Link vorgeschlagen hast. Wir werden ihn sobald wie möglich prüfen. Schließen