She’s my ex

Ich erinnere mich noch sehr genau. Als sich der krabbenfischer und ich damals kennenlernten, bahnte sich eine großartige Freundschaft an.

Wie sich sowas heute abspielt, weiß ich nicht. Wahrscheinlich zeigt man sich sein Smartphone und seine App-Sammlung oder so. Oder man “liked” sich eben. Oder man folgt sich auf Twitter. Das ist für mich alternden Sack eher so meh.

Damals spielte man sich erst einmal stundenlang gegenseitig die Plattensammlung vor. Dieses Vorspielen war ein Ritual mit unzähligen, winzigen Details, deren Berücksichtigung oft über abgrundtiefen Hass oder lebenslange Liebe entschied. Ultimativ bestimmend war die Songauswahl, die in einem mehrstündigen Spannungsbogen orchestriert werden musste.

Da es sich aber um eine oft geübte Tätigkeit handelte und nichts so gut bekannt war wie der Plattenschrank, war dies eher eine leichte Kiste. Viel wichtiger war es, dem unbekannten Charakter des Gegenübers ein Genremix aus Highlights zu choreografieren. Man musste sich praktisch mit einigen vinylen Bauernopfern, die definitiv nicht aus der Lieblingsecke stammten, langsam die Vorlieben seines Gastes erspielen, um sich dann später mit einem Feuerwerk der Musikgeschichte Zuneigung und Respekt zu sichern.

Während dieses Wettbewerbs gab es unzählige Nebenquests: Elegant wurden die Scheiben einhändig aus den weißen Hüllen gezogen, das Auflegen und die begleitenden Worte durften nur solange dauern, dass die Kippe auf dem Zahn nicht die Asche verlor. Wichtig war auch das nahezu beiläufige Aufsetzen der Nadel an exakt der richtigen Stelle. Nicht im Auslaufen des Vorsongs, nicht in den ersten Takten des Stücks.

Nach dem erfolgreichen Anspielen wurde die (unfassbar wichtige) Hülle mit dem unglaublichen Artwork/Foto/Songtext in einer großzügigen Geste dem Gaste zur Verfügung gestellt. Kurz schilderte man eine Szene aus dem besuchten Konzert (wenn möglich).

Ein solches Ritual konnte sich mehrere Tage hinziehen. Über die Zeit stellte sich heraus, ob man zusammen passte oder nicht. Alleine die Tatsache, ob man sich auf so ein Ritual einließ, erhöhte die Chancen allerdings schon enorm.

Wie auch immer, zurück zum Thema: Als der krabbenfischer und ich uns kennenlernten, hatte er sich gerade aus irgendwelchen oder bestimmten Gründen die Haare abschneiden lassen. Die bestimmenden Titel waren Hüsker Düs “Too far down” und Alls “She’s my ex“. Das Leben war brilliant, bunt und aromatisch und diese Songs waren sooo cool, dass man sie heute sogar in Deutschland ohne GEMA-Block hören darf. Ich liebe sie.

Veröffentlicht unter Musik | Hinterlasse einen Kommentar

PHP Code Sniffer und Mess Detector in Netbeans 7.0 integrieren

Netbeans ist seit der 7er Beta mein Standard-IDE auf Mac OS X. Um das Entwickeln von PHP-Anwendungen zu bereichern, habe ich dazu den PHP Code Sniffer und den PHP Mess Detector in Netbeans integriert. Der Code Sniffer warnt mich, sobald ich beim Schreiben des Codes von einem gewissen Standard abweiche. Vordefiniert sind die Coding Standards von PEAR, MySource, PHPCS, Squiz und Zend. Über eine eigene ruleset.xml kann man die Standards aber sehr leicht erweitern, bzw. sich aus den vorhandenen, sogenannten Sniffs einen neuen Standard zusammenbauen. Der Mess Detector macht mich per Fehler- oder Warnmeldung in meinem Tasks-Fenster darauf aufmerksam, dass mein Code bestimmte Grenzen überschreitet: Zyklomatische Komplexität (hehe :), die Grösse von Modulen, zu kurze Variablennamen, ungenutzter Code – trifft also generell eine Aussage über die Stabilität meiner Applikation.

Installation über PEAR

phpmd und phpcs werden über PEAR installiert. Auf Mac OS X hat man PEAR standardmässig im Pfad – d. h. ein Aufruf von pear version im Terminal liefert normalerweise den aktuellen Stand der Installation. Um den aktuellen Code Sniffer zu holen, reicht also ein:

#> pear install PHP_CodeSniffer-1.3.0
downloading PHP_CodeSniffer-1.3.0.tgz ...
Starting to download PHP_CodeSniffer-1.3.0.tgz (327,201 bytes)
...................................................................done: 327,201 bytes
install ok: channel://pear.php.net/PHP_CodeSniffer-1.3.0

Danach steht der Code Sniffer über den einfachen Befehl phpcs auf der Kommandozeile zur Verfügung.

Auch phpmd wird über PEAR installiert, benötigt zusätzlich das Paket von pdepend:

#> pear channel-discover pear.phpmd.org
#> pear channel-discover pear.pdepend.org
#> pear install --alldeps phpmd/PHP_PMD

Auch der Mess Detector steht danach auf der Kommandozeile per Befehl phpmd zur Verfügung. Die Verwendung ist etwas komplizierter, wird in der offiziellen Dokumentation aber ausreichend erklärt.

Das Netbeans-Plugin ziehen und installieren

Es gibt ein kombiniertes Plugin, welches beide Module sofort in die Netbeans Taskliste integriert. Nach Herunterladen wähle ich in Netbeans Tools > Plugins, um mir die Pluginliste anzeigen zu lassen. Unter dem Tab “Downloaded” kann ich dann den Ort für das heruntergeladene Plugin angeben und eine Installation durchführen.

Nach der Installation hat sich das PHP-Menü in den Einstellungen verändert und ich habe zwei neue Reiter: phpMD und phpCodeSniffer:

Um beide Werkzeuge nun in Netbeans zu integrieren, wähle ich den jeweiligen Reiter und muss den Pfad zur entsprechenden Batch-Datei angeben. Ausführbare PEAR-Pakete werden im Standard im Pfad /usr/local/bin/ installiert und sind dort zu finden.

Die rulesets werden auf der phpmd-Webseite erklärt. Ein Klick auf “test settings” sagt uns, ob wir die richtige ausführbare Datei erwischt haben.

Das gleiche Spiel wiederholen wir nun für den CodeSniffer. Auch hier wählen wir den Standard, den wir verwenden wollen. Im Screenshot sieht man, dass ich den PEAR-Standard verwende:

Sind beide Module einmal installiert, gehe ich in mein Projektfenster und öffne eine PHP-Datei. Netbeans verfügt über eine exzellente Filterung von Tasks (eine der Gründe, warum ich derzeit Netbeans vor Eclipse PDT verwende). Ich kann einstellen, ob ich meine Tasks über alle Projekte, ein Projekt, nur offene Dateien oder nur die angezeigte Datei darstellen will. Gleichzeitig kann ich mir Filter bauen wie “Development”, “Quality” oder “TODO”, um mir nur bestimmte Tasks anzeigen zu lassen. Ausserdem lassen sich Tasks als allgemeine oder gruppierte Listen anzeigen. Das macht es einfach, einen Bereich nach dem anderen abzuarbeiten und nicht immer 500+ Todos, Fehler und Warnings mit sich rumzuschleppen.

Wenn man in einem Team arbeitet, sind Mess Detector und Code Sniffer meiner Meinung nach unverzichtbar. Auch wenn man alleine arbeitet, verhindert die Netbeans-Integration beider Werkzeuge so manchen Bug und manchen schlechten Code. Der nächste Schritt ist die Einbindung von den Tools als pre-commit Hook im Versionierungssystem. Aber das machen wir ein anderes mal :)

Veröffentlicht unter PHP, Web-Entwicklung, Werkzeuge | 11 Kommentare

Ein kurzer Blick auf den Status der PHP-Entwicklung

In den letzten Jahren hat sich in PHP extrem viel getan. Nach einem anfänglich doch belächeltem Status ist PHP zu einer mächtigen Instanz herangereift, fundiert auf kontinuierlicher Entwicklung, flankiert durch unzählige Tools und getragen durch eine aktive Community. Mittlerweile ist PHP ein Big Player – wen wundert es da, dass der Einstieg für Programmierer immer komplexer wird. Man kann natürlich immer noch in Sekunden ein paar Zeilen prozeduralen PHP-Code raushauen. In der folgenden Übersicht versuche ich aber mal ein paar Anlaufstellen aufzuzeigen, mit denen man sich nach dem Einstieg oder auch noch mit jahrelanger Erfahrung auf jeden Fall beschäftigen sollte.

IDE

Die Abkürzung IDE steht für Integrated Development Environment. Neben den klassischen, kleinen Text-Editoren gibt es bereits einige Baukästen, die sich auf PHP spezialisiert haben oder einen Funktionsumfang für PHP anbieten. Der Sinn hinter IDEs ist die Integration unterschiedlicher Werkzeuge in einer Software. Meistens durch optionale Plugins unterstützt, verwende ich also nicht für verschiedene Arbeitsschritte unterschiedliche Programme, sondern steuere meine Entwicklung aus einer Applikation heraus. Zur Auswahl stehen Eclipse PDT, Zend Studio, Aptana, NetbeansPHPStorm und die Komodo IDE (sicher was vergessen, oder? Schreib’s in die Kommentare). Alle IDEs haben Stärken und Schwächen. Im Grunde bieten sie aber einen ähnlichen, wenn nicht sogar identischen Funktionsumfang.

Debugging

PHP ist eine serverseitige Skriptsprache. Zur Überprüfung meiner Arbeit während der Erzeugung des Codes brauche ich also mindestens einen Server als Interpreter. Klassisches Debugging besteht aus der expliziten Ausgabe des Programmzustandes in meinem Code und einer Überprüfung dieser Ausgabe durch Aufruf meiner Entwicklung im Browser oder in den Server-Logfiles. Das ist doof. Debugger wie der Zend Debugger oder Xdebug erleichtern mir die Arbeit und erzeugen Ausgaben und Informationen bereits während der Erstellung des Codes. Beide lassen sich hervorragend in IDEs einbinden.

Tests

Testen sieht meistens so aus: Applikation im Browser aufrufen und so lange probieren, bis man ein vages Gefühl der Sicherheit bekommt. Falsch! PHPUnit bietet automatisierte Tests von atomaren Bestandteilen meines Codes bis hin zur Erzeugung von komplexen Testsuites, um bei sauberer und umsichtiger Anwendung jederzeit ein Qualitätsbild meiner Entwicklung zu zeichnen. SimpleTest macht das auf ähnliche Art und Weise. Selenium liefert mir noch die zusätzliche Option, funktional, aber automatisiert im Browser zu testen – per Makros. Selenium lässt sich übrigens fein in PHPUnit integrieren und von dort aus steuern.

Analyse

Wer hat schon einmal wirklich seinen Code analysiert? Anzahl Klassen? Komplexität? Mit Werkzeugen wie phploc und pdepend schafft man sich schnell einen Überblick. Die Ergebnisse sind nicht einfach zu verstehen oder zu interpretieren, gehören aber zu den erforderlichen Standards, sobald Projekte mal etwas grösser werden. phpcpd liefert dazu die Menge von dupliziertem Code in meinen Modulen. Zeit für Refactoring :)

Qualität

Natürlich programmiert jeder sauber. Der PHP Code Sniffer und der PHP Mess Detector unterstützen das ganze jedoch auch noch mit Audits und Kennzahlen. Der Code Sniffer sorgt für ein einheitliches Bild und verhindert, dass ich schludere – im Code, wie auch in der Dokumentation. Der Mess Detector macht mich darauf aufmerksam, wenn ich nicht ausreichend abstrahiere, zuviel in eine Code-Passage packe oder Variablen nicht sauber benenne.

Dokumentation

Ohne Zweifel: Eine automatisierte Dokumentation gehört zu jedem PHP-Projekt. Ganz einfach geht das mit dem phpDocumentor. JavaDoc-ähnlich werden meine Kommentare im PHP-Code automatisch in eine ansehnliche HTML-Oberfläche verwandelt.

Versionierung

Zugegeben: Versionierung hat nicht viel mit PHP zu tun sondern ist eher ein generelles Werkzeug in der Software-Entwicklung. Trotzdem kann man nicht genug betonen: Software-Entwicklung benötigt Versionierung. Klassisch geht das mit CVS (ja, gibt’s auch noch) und SVN. Erfahrene, Mehrversteher und Disziplinierte verwenden .git oder Mercurial.

Build und Deployment

Gerade die Tatsache, dass man seine PHP-Anwendungen nicht kompilieren muss, war ja eine der Vorzugsargumente für den Einstieg in PHP, oder? Wenn man komplexere Projekte entwickelt, sehnt man sich jedoch nach Automatisierung durch Build-Skripte. Mit ant oder phing verwende ich XML-Instruktionen, um mein Testing, Staging oder Deployment zu automatisieren. Im Build kann ich dann viele der oben genannten Werkzeuge implementieren. Automatisiertes Durchlaufen meiner Testsuites, Codeanalyse, Trennung von Test- und Produktivcode, Export aus der Versionierung, Up- bzw. Download per sFTP, Verzeichnisse anlegen, Dateien kopieren, umbenennen, löschen oder Skripte ausführen.

Einsatz

Unerlässlich für Installation und Einsatz der meisten Tools ist PEAR, eine Paketverwaltung für die Kommandozeile aller Betriebsysteme. Für Netbeans und Eclipse-basierte IDEs gibt es weitere Plugins. Z. B. bietet PTI als Eclipse-Plugin eine ganze Toolbox auf einmal. Für Netbeans gibt es ein PHP Mess Detector und PHP Code Sniffer-Plugin. Wer schlau ist, nutzt einen Aggregator von Gregor Krsteski für alle Analysen auf einmal über PHP auf der Kommandozeile.

Zur kontinuierlichen Integration von allem stehen mehrere Systeme zur Verfügung: Hudson, Jenkins oder phpUnderControl.

Viel Spass beim Stöbern und Lernen.

Veröffentlicht unter PHP, Web-Entwicklung | Hinterlasse einen Kommentar

Ein paar Kniffe für die WordPress functions.php

Die Datei functions.php in einem WordPress-Theme ist der Standard für den Eingriff in den WordPress-Kern. Neben Plugins, die man natürlich auch entwickeln kann, sollte ein Entwickler tunlichst diese Funktionsbibliothek zur Anpassung und Erweiterung von WordPress nutzen, um sich immer die Möglichkeit zum Upgrade zu behalten.

In dieser zentralen Datei kann ich auf sogenannte Hooks zugreifen, die in Filter-Hooks und Action-Hooks aufgeteilt sind. Das heißt, ich kann meine Funktionen zu bestimmten Zeitpunkten bei der Zusammenstellung des WordPress-Inhaltes meiner Seite durch die WordPress-Engine einhängen. Weiterhin kann ich einige optional verfügbare Module in WordPress ansprechen und konfigurieren. Dazu gehören unter anderem der Thumbnail-Support, die benutzerdefinierten Menüs oder die Widgets.

Hier sind ein paar Funktionen, die ich bei meiner Arbeit am hasematzel.de-Theme zusammengetragen habe:

Support für Windows Live Writer

Wer Windows Live Writer nicht verwendet, der kann den Link auf das notwendige Manifest aus dem Kopf der Seiten entfernen. Dadurch spart man eine Zeile im <head>-Bereich seiner Seite.

/**
* Remove Windows Live Writer
* @link http://wp-snippets.com/remove-wlwmanifest/
*/
remove_action('wp_head', 'wlwmanifest_link');

RSD-Link aus dem head entfernen

Really Simple Discovery ist ein XML-Dialekt, um externe Werkzeuge und Publishing-Software an das Blog anzubinden, beziehungsweise um bestimmte Funktionen des Blogs anderen Werkzeugen zur Verfügung zu stellen. Wer nur über die WordPress-Oberfläche bloggt, sollte den Eintrag ohne Nebeneffekte aus dem <head> entfernen können. Wieder eine Zeile weniger.

/**
* Remove RSD link
* @link http://wp-snippets.com/remove-rsd-link/
*/
remove_action('wp_head', 'rsd_link');

Standard-Stylesheets für Kommentare entfernen (ab Version 2.9.1)

Für das Recent comments-Widget gibt es immer eine Style-Definition im Kopf der HTML-Seite. Dieser wird automatisch hinzugefügt, ob man das Widget nun nutzt oder nicht. In den WordPress-Versionen zwischen 2.8 und 2.91 hat sich der Zugriff auf diesen Filter verändert. Eine gesamte Historie und eine umfangreiche Erklärung kann man im webstractions-Blog nachlesen. Es empfielt sich, die eine Zeile CSS in das eigene Theme-CSS zu übernehmen, um nicht überrascht zu werden, wenn man sich später einmal entscheidet, das Recent comments-Widget zu aktivieren.

.recentcomments a {
    display: inline !important;
    padding: 0 !important;
    margin: 0 !important;
}
/**
* Remove recent comments styling
* @link http://webstractions.com/wordpress/remove-recent-comments-inline-styl/
*/
if (!function_exists('my_remove_recent_comments_style')) {
    function my_remove_recent_comments_style()
    {
        global $wp_widget_factory;
        remove_action(
            'wp_head', array(
                $wp_widget_factory->widgets['WP_Widget_Recent_Comments'],
                'recent_comments_style'
            )
        );
    }
    add_action('widgets_init', 'my_remove_recent_comments_style');
}

Noch ein Wort zu Funktionen: Es ist eine gute Angewohnheit, mit Funktionsnamen zu arbeiten, die offensichtlich als custom-Funktionen zu erkennen sind. Zusätzlich sollte man die Funktionsdefinition und das Einbinden in den Hook mit der PHP-Funktion function_exists() absichern.

Webanalyse-Code nur unter Bedingungen einbinden

Wer ein Analyse-Tool verwendet, welches auf einen Pixelabruf oder einen JavaScript-Tracker angewiesen ist, der sollte diesen nur auf der LIVE-Webseite und nur für andere Benutzer als sich selbst aktivieren. Meistens müssen diese Dinger im head-Bereich oder am Ende der Seite stehen. Die Anzeige kann man dann einfach an die Bedingungen knüpfen:

if (!function_exists('my_page_tracker')) {
    function my_page_tracker()
    {
        // No tracking if logged in as admin
        if (current_user_can('level_10')) {
            return '';
        }
        // No tracking if is dev environment
        if ($_SERVER['HTTP_HOST'] == 'hasematzel.local') {
            return '';
        }
        echo "... my tracking code ...";
    }
    add_action('wp_head', 'my_page_tracker');
}

Anzeige der WordPress-Signatur unterdrücken

WordPress meldet sich selbst mit der Versionsnummer im Kopf der HTML-Seite. Auch diese eine Zeile kann – wer möchte – entfernen.

/**
* Remove wordpress generator element
* @link http://wp-snippets.com/remove-meta-generator/
*/
remove_action('wp_head', 'wp_generator');

Weitere nützliche Tipps & Tricks

Es gibt natürlich mittlerweile unzählige Quellen zum Thema WordPress-Anpassungen. Den WordPress-Codex selbst finde ich reichlich unübersichtlich: Ein paar Sachen sind hervorragend erklärt, manche Sachen sucht man vergeblich. Auf ein paar Quellen möchte ich aber noch direkt hinweisen:

Veröffentlicht unter Tipps & Tricks, Wordpress | Hinterlasse einen Kommentar

Überlegungen zur Gestaltung von Tabellen

Über @webstandardsmag gerade einen fantastischen Tweet reinbekommen: Janko Jovanovic und Theresa Neil schreiben über UI pattern von Tabellen und zeigen in Ihren Posts anhand unzähliger Beispiele, welche Anwendungsfälle und Lösungen existieren.

Veröffentlicht unter UI | Verschlagwortet mit , , | Hinterlasse einen Kommentar

Ansprechbare Buttons mit visueller Reaktion und CSS3

Die HTML5- und CSS3-Unterstützung in den aktuellen Browsern und Surfclients dieser Welt ist sicherlich noch mangelhaft. Manchmal darf man jedoch Applikationen entwickeln, bei denen es auf eine flächendeckende Unterstützung nicht so sehr ankommt. Das gilt z. B. für manche Intranets oder Applikationen mit beschränkten Zugangsberechtigungen.Ich habe in der letzten Zeit einige, sogenannte Backoffices gebaut (Messeclients etc.) und es hat mir enorm viel Spass gemacht, dabei neuere Elemente und CSS-Angaben verwenden zu können, weil ich mir über die korrekte Darstellung sicher sein konnte.Wenn man z. B. Desktop-ähnliche Webapplikationen für Prism entwickelt, darf man auf den vollen Schwung von Properties zugreifen, die derzeit vom Mozilla-Projekt unterstützt werden. (Naja, zumindest fast) Mit wenigen Zeilen CSS hat man so schnell einen feinen, ansprechenden Button gebastelt, der bei Interaktion mit der Maus brav ein reaktives Verhalten zeigt. Hier erstmal das HTML:

<!DOCTYPE html
    PUBLIC"-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
    <title>XHTML 1.0 Transitional</title>
</head>
<body>
<div id="wrapper">
    <form>
        <button type="submit" class="save">Save</button>
        <button type="submit" class="cancel">Cancel</button>
    </form>
</div>
</body>
</html>

Das Formular ist nicht funktional und dient nur der Demonstration. Kommen wir lieber zum CSS. Zunächst geben wir dem #wrapper einen Hintergrund:

#wrapper {
    width: 400px;
    height: 200px;
    background-color: #ddd;
    padding: 50px;
}

Dann geben wir den Buttons mit ein wenig CSS3 ein bisschen Schick:

button {
    background-color: #ddd;
    background-image: -moz-linear-gradient(bottom center, #ccc, #ddd);
    border: 1px solid #999;
    border-top-color: #eee;
    border-left-color: #eee;
    color: #333;
    font-weight: bold;
    text-shadow: 1px 1px 1px #fff;
    padding: 3px 8px;
    cursor: pointer;
    -moz-border-radius: 5px;
    -moz-box-shadow: 2px 2px 3px #ccc;
}

Das erste Resultat sieht dann so aus:

Über das cursor: pointer lässt sich bekanntlich streiten. Ich mag es, weil es ein visueller Indikator dafür ist, dass hier eine Aktion erfolgen kann.

Visuelle Reaktion

Als nächste beschäftigen wir uns mit der visuellen Rückmeldung der Buttons, den verschieden states beim Überfahren und beim Klick. Zunächst die Pseudoklassen :hover und :focus. Der Abbrechen-Button erhält dabei ein eigenes Benehmen, die Schriftfarbe soll sich beim :hover ändern.

button:hover, button:focus {
    -moz-box-shadow: 2px 2px 3px #aaa;
}
button.cancel:hover, button.cancel:focus {
    color: #f60; /* Fast orange */
}

Der :hover-Status hebt den Button visuell an (über die shadow-Property):

Der Save-Button wird hervorgehoben.

Der Cancel-Button erhält noch einen Farbwechsel.

Der tatsächliche Klick nutzt dann die :active-Pseudoklasse, um die Aktion farblich zu unterstreichen. Der Save-Button bekommt eine grüne, der Cancel-Button eine rote Schrift:

button.save:active {
    color: green;
}
button.cancel:active {
    color: #c00;
}

Der :active-State für Save.

Der :active-State für Cancel.

Fertig! Wir haben keine Grafiken verwendet, die einen weiteren HTTP-Request notwendig machen würden. Findige Webdesigner können sicherlich die paar Zeilen für die Webkit-und anderen Browser-Abkömmlinge hinzufügen. Mit ein bisschen Bastelei hat man die Buttons sicherlich auch in älteren Browsern, die ggf. noch unterstützt werden müssen, ergänzt. Obwohl das reaktive Verhalten der Buttons für Menschen mit Wahrnehmungsschwächen nicht optimal ist, kann diese Lösung eingebaut werden. Ohne CSS und state-changes hat man immer noch zwei klassische Buttons.

Veröffentlicht unter Design, HTML & CSS | Verschlagwortet mit , , , | Hinterlasse einen Kommentar

Bücherliste für den Urlaub 2010

Auch wenn der Sommer sich hierzulande vielleicht nicht im Wetter zeigt, so ist doch zumindest ein Urlaub angesagt. Damit die Weiterbildung nicht zu kurz kommt, hier meine Bücherliste für eine gepflegte Lektüre am Abend:

Es fehlen noch ein paar Bücher. The Cluetrain Manifesto habe ich noch nicht gelesen (mittlerweile in der 10-Jahres-Jubiläumsausgabe, tsts). Irgendwas Leichtes wäre auch nicht schlecht. Naja, ich werde die Liste wohl nach und nach aktualisieren.

Veröffentlicht unter Bücher | Hinterlasse einen Kommentar

RSS-Feeds mit YQL aggregieren und abrufen

YQL hatte sich innerhalb kürzester Zeit zu einem meiner Lieblingswerkzeuge gemausert. Schon seit über einem Jahr hatte Yahoo!s Developer Evangelist Chris Heilmann in regelmäßigen Abständen die Fähigkeiten der API für APIs unter Beweis gestellt. Die Yahoo! Query Language ist eine SQL-ähnliche Syntax, unter deren Verwendung man alle möglichen Dritt-Schnittstellen einheitlich abrufen kann. Die kleinen Beispiele in diesem Artikel sollen zeigen, welchen Einsatzzweck diese Schnittstelle haben kann. Werfen wir mal einen Blick auf einen einfachen Aufruf:

select * from html where url='http://mashable.com'

Diese Query ist relativ sinnfrei, liefert sie doch das gesamte body-Konstrukt der mashable.com-Startseite. Dennoch erkennt man schon das Potenzial, wenn man für den Zugriff auf Inhalte eine Art SQL anwenden kann. Öffnet man diese Query in der YQL-Konsole, kann man sich die Rückgabewerte anzeigen lassen.Nehmen wir einmal an, mashable.com hätte keinen RSS-Feed, wir möchten aber gerne die neuesten drei News abrufen und in unserer Webseite zeigen. Mit ein bisschen xpath-Magie und einen Blick in den Quelltext ist das kein Problem. mashable.com verwendet WordPress und versteckt seine News in einem div-Element und dort in einem h2/a-Konstrukt. Eine Funktion reduziert die Resultate auf die obersten 3. In Verbindung mit einer XML-Query sieht unsere Abfrage also so aus:

select * from html
    where url='http://mashable.com'
    and xpath='//div/h2/a' | truncate(count=3)

Am besten schaut man sich das Resultat wieder in der YQL-Konsole an. Wählt man JSON als Output und ruft das Ganze über die API ab, kann man leicht durch das Resultat iterieren.

Abruf von mehreren Feeds

Wie der Abruf eines HTML-Konstruktes ist auch das Einlesen von RSS-Feeds überaus einfach. Nehmen wir an, ich möchte die letzten Einträge des Hasematzel-RSS einlesen – und zwar nur die Titel, Links und das Veröffentlichungsdatum der einzelnen Einträge. Die Query sieht dann so aus:

select title, link, pubDate from rss
    where url='http://feeds.feedburner.com/hasematzel'

Im Ausgabefenster der Konsole sind die Einträge nach Datum absteigend sortiert. Das liegt bei RSS in der Natur der Dinge. Bei der Aggregierung von mehreren Feeds bekomme ich aber die Feeds (nicht die Beiträge) nacheinander angezeigt. Ich rufe mal meinen delicious.com-Feed und meinen Twitter-Feed ab:

select title, link, pubDate from rss
    where url in (
        'http://twitter.com/statuses/user_timeline/818226.rss',
        'http://feeds.delicious.com/v2/rss/hasematzel?count=15')

Bei zwei Feeds könnte man ja noch schnell ein bisschen Basteln, die Rückgabe auseinandernehmen und die Arrays/Objekte in der richtigen Reihenfolge wieder zusammenfügen. Je mehr Feeds man aber aggregiert, umso umständlicher wird das. Zusätzlich bürde ich meinem Code zusätzliche Arbeit auf, die auch YQL verrichten kann.

select title, link, pubDate from rss
    where url in (
        'http://twitter.com/statuses/user_timeline/818226.rss',
        'http://feeds.delicious.com/v2/rss/hasematzel?count=15',
        'http://oliverschwarz.tumblr.com/rss',
        'http://piepmatzel.de/feed/')

Sortieren und Abschneiden

Für die Sortierung (und auch das Abschneiden) von Daten hat das YQL-Team spezielle Funktionen bereitgestellt. Die Funktionen werden einfach am Ende der Query positioniert. So ist es möglich, zunächst nach pubDate aufsteigend zu sortieren und das Resultat zusätzlich auf maximal fünf Einträge zusammenzuschneiden:

select title, link, pubDate from rss
    where url in (
        'http://twitter.com/statuses/user_timeline/818226.rss',
        'http://feeds.delicious.com/v2/rss/hasematzel?count=15',
        'http://oliverschwarz.tumblr.com/rss','http://piepmatzel.de/feed/'
    ) | sort(field='pubDate',descending='true') | truncate(count=5)

So einfach ist das mit YQL. Der Spasseffekt kommt dann auf, wenn ich das nicht nur in der YQL-Konsole mache, sondern die Resultate über die API abrufe. Dazu wird es dann noch einmal einen zusätzlichen Beitrag geben. In Chris Heilmanns github-Account gibt es dazu auch schon jede Menge Beispiele. Vor dem Einsatz in produktiven Systemen sollte damit gerechnet werden, dass die YQL-API auch mal nicht da sein kann. Es empfiehlt sich, die Ergebnisse für einen gewissen Zeitraum zu cachen (Dirk Ginader hat dazu eine einfache Lösung).

Veröffentlicht unter Tipps & Tricks, Tutorial, Werkzeuge | Verschlagwortet mit , , , , | 5 Kommentare

Variablen aus PHP per JSON in JavaScript übergeben

Es passiert mir recht oft, dass ich in einer Applikation im JavaScript-Layer auf die Werte von Variablen zugreifen muss, die eigentlich nur in PHP existieren. Meist habe ich mir in PHP ein Wörterbuch angelegt, welches Standardbegriffe enthält, die an vereinzelten Stellen in der Applikation verwendet werden. Zum Beispiel werden Fehlermeldungen (“konnte nicht gespeichert werden”, “bitte Feld %s ausfüllen”) in einer einzigen Datei zusammengefasst und zum notwendigen Zeitpunkt abgerufen und angezeigt. Das ermöglicht mir unter anderem später eine Lokalisierung der Applikation.Ich beginne im Normalfall immer mit dem Backend (PHP) und setze erst später den Client-Layer (JavaScript) um. Das meiste JavaScript ist dann eine Verbesserung der Usability. Nicht selten brauche ich an manchen Stellen im JavaScript auch eine Fehlermeldung, die aber nur in PHP existiert.

Der Holzhammer

Die einfachste Methode ist der print() der Variable direkt in das JavaScript:

<?php
$error = 'Es ist ein Fehler aufgetreten';
?><!DOCTYPE html>
<html lang="de">
<head>
...
<script type="text/javascript">
    var error = '<?php echo $error; ?>';
    alert(error);
</script>

Die Methode ist effektiv, hat aber gehörige Nachteile:

  1. Ich habe manchmal nicht die Möglichkeit, mit PHP noch im HTML/DOM rumzuwerkeln. Manchmal will ich sie auch gar nicht haben.
  2. Diese Lösung verursacht eine Sprach-Suppe, die nur sehr schwer zu betreuen ist.
  3. Bei grösseren Wörterbüchern kommt man hier ganz schön ans Schwitzen.

Etwas eleganter: Ein bisschen JSON

Die JavaScript-Objekt-Notation, kurz JSON genannt, bietet einen etwas eleganteren Weg, auch grössere Mengen von Variablen von PHP in JavaScript zu transferieren:

<?php
$errors = array(
    'errnosave' => 'Speichern fehlgeschlagen',
    'errunknown' => 'Unbekannter Fehler'
);
?><!DOCTYPE html>
<html lang="de">
<head>
...
<script type="text/javascript">
    var errors = '<?php echo json_encode($errors); ?>';
    alert(errors.errunknown);
</script>

Diese Methode hat schon einige Vorteile, aber immer noch ein paar Nachteile:

  1. Ich kann schon einige Daten an JavaScript übertragen. Das JSON-Format ist genial kurz und erzeugt für diese Aufgabe fast keinen Overhead.
  2. Nachteil: Ich muss immer noch direkt ins Dokument schreiben.

Erzeugen einer eigenen dictionary.js

Diese dritte Variante bemüht sich, einfach, aber so abstrakt wie möglich den Variablentransfer durchzuführen. Wir brauchen dafür drei Dateien und – wenn möglich – einen Cron, der regelmässig das Wörterbuch erzeugt.

Datei Nr. 1: Die dictionary.ini

In der dictionary.ini werden die Variablen abgelegt. Eine ini-Datei, weil man sie aus PHP heraus mit der Funktion parse_ini_file() so schön lesen und weiterverarbeiten kann. Eine ini-Datei ist ein einfaches Textdokument und kann so aussehen:

; Statische Meldungen
[authentication]
variable = "Wert"
variable2 = "Wert2"

[errors]
errnosave = "Es wurde nicht gespeichert"
errunknown = "Unbekannter Fehler"

Den Aufbau kennt man z. B. von den Smarty-Config-Dateien.

Datei Nr. 2: Der Parser create_dictionary.php

Ich kann meinen Parser in der Datei create_dictionary.php nun anweisen, die ini-Datei einzulesen und dabei die Sektionen (in den eckigen Klammern) zu berücksichtigen:

<?php
$dictionary = parse_ini_file('dictionary.ini', true);
$errors = $dictionary['errors']; // Sektion 'errors' ermitteln
?> 

Die dritte Datei: dictionary.js

Nun kann ich den Array $errors im JSON-Format in eine Datei namens dictionary.js schreiben:

<?php
$data = sprintf('var DICT = %s', json_encode($errors));
$h = fopen('dictionary.js', 'w');
fwrite($h, $data);
fclose($h);
?>

Diese dictionary.js-Datei kann ich nun ganz normal im <head>-Bereich meiner HTML-Seite einbinden und habe Zugriff auf das DICT-Objekt:

<!DOCTYPE html>
<html lang="de">
<head>
...
<script type="text/javascript" src="dictionary.js"></script>
<script type="text/javascript">alert(DICT.errunknown);</script>

Auch diese Methode kommt nicht ganz ohne Nachteile daher:

  1. Ich muss aus PHP in eine dictionary.js schreiben können, manchmal will man das aus Sicherheitsgründen nicht.
  2. Ich will eine solche Schreiboperation nicht bei jedem Request auf die Applikation durchführen. Ich muss das also per Cronjob oder immer in einem Build machen.

Dennoch ist die Variante “schön” genug, um in einzelnen Fällen und gerade in Web-Applikationen die Übermittlung von Variablen von PHP zu JavaScript zur Leichtigkeit werden zu lassen.

Veröffentlicht unter JavaScript, PHP, Tipps & Tricks, Web-Entwicklung | Verschlagwortet mit , , , | 3 Kommentare

Social Media heute und morgen

Zwei Beiträge über Social Media haben mich in dieser zweiten Wochenhälfte angenehm überrascht. Jeder Beitrag geht auf völlig unterschiedliche Situationen ein. Mike Schnoor beschreibt in seinem Blog, was aus seiner Sicht 2010 im Bereich Social Media passieren wird. Dabei erfasst er die Spitze des Social Media-Eisbergs, die Early Adopters, die Treiber und Erfinder. Im Grunde zeichnet er eine Fortsetzung der aktuellen Bewegung. Mehr Nutzer, mehr Bedarfe, weniger Kontrolle für herkömmliche Broadcaster usw. Ohne die Qualität seiner 10 Punkte einzeln bewerten zu wollen, kann ich mir vorstellen, dass sich der Bereich Internet so oder so ähnlich entwickeln wird. Gerade Unternehmen werden sich aus unterschiedlichen Gesichtspunkten mehr und mehr gezwungen sehen, auf Züge aufspringen zu müssen. Der eine oder andere Zug kann dabei für das eine oder andere Unternehmen durchaus zu schnell sein.

Nur ein neuer Marketing-Kniff?

Es wird noch lange dauern, bis der Grossteil der Unternehmen feststellt, dass es sich bei Social Media nicht um einen weiteren Marketing-Kniff handelt. Dass es nicht nur eine Marketing-Verantwortung ist, sich um das grosse Potenzial zu kümmern. Es wird stattdessen Zeit brauchen, zu erkennen, dass ein intensiver Wechsel in der Unternehmenskultur stattfinden muss, um sich auf Social Media einzulassen. Manche Unternehmen bringen das aufgrund ihres Produktes oder ihrer Dienstleistung mit, vielleicht auch aufgrund der Branche oder des Durchschnittalters der Mitarbeiter. Andere Unternehmen werden Schwierigkeiten haben, den Einstieg jemals in absehbarer Zeit zu schaffen. Persönlich halte ich den Denkansatz “Social Media/Crowd Sourcing/User Generated Content/Insert Buzzword Here ist ein Potenzial, welches abgeschöpft werden muss” für völlig falsch. Vorher muss der Komplex erst verstanden werden, dann muss eine Entscheidung erfolgen, ob man sich überhaupt auf dieses Internetz einlassen will. Vielleicht wird auch eine friedliche Koexistenz zwischen Klassik und Moderne angestrebt. Gibt es soetwas?

Der Zug ist weg, was nun?

Kommen wir also zum zweiten Beitrag. Seth Godin veröffentlicht die Aufgabenliste für den Fall, dass es schon zu spät ist: “Is it too late to catch up?“, fragt er. Damit richtet er sich an die Konservativen, die Langsamen, die Verweigerer und Ängstlichen. Was ist, wenn mein Unternehmen noch nicht dabei ist? Kann man den Rückstand mit GMail und 11 Punkten auf der Liste aufholen? Muss ich, wie er im letzten Punkt beschreibt, wirklich scheitern, um zu verstehen?Unternehmenskulturen sehen sich neuen Herausforderungen gegenübergestellt. Klassische, starre Kommunikationswege werden aufgelöst. Das Internet als neuer Senderkanal für das Marketing ist in Wirklichkeit ein Bündel von Millionen Kanälen. Und diese Kanäle sind auf einmal keine Einbahnstrasse mehr. Resourcen sind ohnehin knapp und bei gegenwärtiger Arbeitslast ist die Bewältigung neuer Aufgaben kaum möglich. Es müssen sich erst ganze Prozessketten ändern, bevor Platz geschaffen wird für neuen Input, neue Kommunikation. Seths Artikel zaubert ein bisschen augenscheinliche Leichtigkeit in diese Aufgabe, meiner Meinung nach zu viel davon. Aber ein Kernsatz in seinem Artikel ist wichtig: “Mach doch einfach”. Eine schöner Vorsatz für das neue Jahr.

Veröffentlicht unter Social Media | Verschlagwortet mit , , | Hinterlasse einen Kommentar