Sollte man target=“_blank“ noch mal eine Chance geben?

Ich weiß, das ist ein heisses Pflaster auf das ich mich da begebe. Zum einen ist das Attribut nicht XHTML-Strict und zum anderen ist es ja in der Tat sehr lästig, wenn man beim Surfen andauernd neue Fenster/Tabs aufgemacht bekommt. Besonders ärgerlich ist das bei so Müllseiten, die sogar interne Links mit target="_blank" versehen haben.

Die Begründungen sind einleuchtend und für den versierten Internetbenutzer geht das „Öffnen in einem neuen Tab“ genauso leicht von der Hand wie ein normaler Klick auf einen Link. Aber wie sieht das bei mobilen Browsern aus? Ich glaube, ich kann die Zahl der länger halten bis das PopUp aufgeht und dann „In neuem Tab öffnen“ antippen locker an einer Hand abzählen.

Je nach Zielgruppe einer Website (mobile und nicht so internetaffin) sehe ich da ein target="_blank" gar nicht als das schlimme Übel an. Es kann tatsächlich für beide Seiten ein Gewinn sein: den Seitenbetreiber und den Surfer.

CSS-Frameworks: Bootstrap / Foundation

Ich bin kein Designer. Ich habe zwar ein ästhetisches Empfinden, kriege es aber nicht auf die Reihe mittels HTML und CSS irgendwas halbwegs anständiges auf die Beine zu bringen. Zu meiner Rettung gibt es CSS-Frameworks wie Bootstrap und Foundation.

Bootstrap war das erste CSS-Framework, dass ich genutzt habe. Und wie es bei so vielen Sachen ist: wenn man zu viel davon benutzt, wird es irgendwann langweilig. Ich habe mich einfach satt daran gesehen. Denn wie ich schon sagte: ich bin kein Designer und kann leider nicht mit ein paar handvoll Zeilen CSS das ganze so anpassen, dass es nicht mehr nach Bootstrap aussieht. Deshalb habe ich mich jetzt für ein neues Projekt mal an Foundation gewagt. Meine Erfahrung mit Foundation ist also noch recht klein, aber für einen ersten Vergleich reicht es.

Bootstrap Fluid

Bootstrap kommt mit einer großen Anzahl an verschiedenen Elementen daher, wobei im Vergleich zu Foundation eher die Zahl der Variationen überwiegt. Und die Dokumentation ist besser. Bei Foundation muss ich immer mal wieder rätseln, wie ein in der Doku angesprochenes Feature wohl umgesetzt wird.

Dafür kommt Foundation mit wesentlich weniger Klassen im Markup aus. So wenigstens mein Eindruck bei der Anpassung des vorher in Bootstrap gebauten Layouts.

Foundation, Rapid-Prototyping

Beide Frameworks basieren auf Grids und sind auf responsive Design ausgerichtet, wobei Bootstrap 3 „mobile-first“ sein wird. Bislang habe ich mich nicht übermäßig mit Anpassungen für mobile Endgeräte gekümmert, aber auf den ersten Blick scheint mir Foundation hier expliziter und damit klarer zu sein, was die Klassennotationen angeht.

Der Umstieg von dem einen Framework zum anderen ist nicht so schwierig, zumindest so lange man noch keine eigenen CSS-Anpassungen vorgenommen hat. Bootstrap scheint mir einfach verbreiteter zu sein, so findet man schneller Beispiele für die Verwendung in diverse PHP-Frameworks. Bei Symfony2 fällt da insbesondere das Form-Theming ins Gewicht. Andererseits sehen meine Formulare beim Foundation-Projekt auch ohne ein spezielles Theme im Moment ganz OK aus.

Verwirrend bei Foundation ist auf jeden Fall, dass deren Website selbst Komponenten benutzt, die nicht im Framework enthalten sind. Ich fand ein paar Elemente der Website nämlich ganz cool und habe versucht diese nachzubauen, bis ich dann feststellen musste, dass die gar nicht in Foundation enthalten sind.

Ich werde das Projekt aber auf jeden Fall mal in Foundation durchziehen. Mal abwarten, auf welche Überraschungen und Probleme ich noch treffen werde.

Vine-Videos im eigenen Blog einbetten

Vorerst gibt es noch keine offizielle Möglichkeit, sich aus den eigenen (oder fremden) Vine-Videos einen Code-Snippet für das eigene Blog zu erstellen. Technisch ist das aber durchaus möglich.

Um das zu vereinfachen, habe ich ein kleines Bookmarklet geschrieben. Um es benutzen zu können, zieht folgenden Link einfach in eure Lesezeichenliste:
Vine-Bookmarklet: https://twitter.com/th1nk/status/295994006347857920

Auf dieser Seite klickt ihr nun auf das Bookmarklet in der Lesezeichenleiste und schon öffnet sich ein kleines Fenster mit dem Code, den ihr für euer Blog benutzen könnt. Hier noch mal standesgemäß als Vine-Video :)

Native SQL-Anfragen in Doctrine / Symfony2

Ich bin jetzt schon seit längerem ein großer Fan von Symfony 2 und verwende Doctrine als ORM. Das klappt alles super, manchmal muss man sich aber in die Grenzgebiete wagen.

Im vorliegenden Fall ging es um Statistikwerte in einer Tabelle. Im wesentlichen besteht die Tabelle (neben einer ID) noch aus einem Timestamp und um einen Wert, der im aktuelle Fall immer zwischen 1 und 3 liegt und eine Bewertung darstellt. Die Tabelle selbst wird auch in einer Entität abgebildet folgende einfache Query sollte aber nun umgesetzt werden:

SELECT DATE(created_at), rating, COUNT(rating) 
FROM ratings 
GROUP BY DATE(created_at), rating 
ORDER BY DATE(created_at) ASC, rating ASC;

Damit wollte ich also eine Zeitreihe erhalten, die neben dem Datum noch enthält, wie häufig die entsprechende Bewertung an dem Tag vorkam.

Hierzu musste ich auf die NativeQuery von Doctrine zurückgreifen. Die Ergebnisse werden aber trotzdem von Doctrine verwaltet und verlangen ein ResultSetMapping, damit Doctrine weiß, wie die Ergebnisdaten umgesetzt werden sollen. Damit lässt sich zum Beispiel bewerkstelligen, dass Doctrine automatisch passende Objekte zurückgibt, die die Daten enthalten.

In meinem Fall wollte ich aber nur die nackten Zahlen haben, da ich die Werte zur späteren Visualisierung in JS eh noch einmal umschreiben muss. Den Code habe ich in einem EntityRepository gekapselt, wer einen ähnlichen Code in einem Service oder einer Controller-Action verwenden will, muss sich ggf. anderweitig den EntityManager besorgen. So sieht der Code aus:

$rsm = new \Doctrine\ORM\Query\ResultSetMapping();
$rsm->addEntityResult('CfMainBundle:Rating', 'r');
$rsm->addScalarResult('dateCreatedAt', 'date');
$rsm->addScalarResult('rating', 'rating');
$rsm->addScalarResult('countRating', 'count');
$data = $this->getEntityManager()
    ->createNativeQuery(
        'SELECT DATE(r.created_at) AS dateCreatedAt, r.rating, COUNT(r.rating) AS countRating
          FROM ratings r
          GROUP BY DATE(r.created_at), r.rating
          ORDER BY DATE(r.created_at) ASC, rating ASC',
         $rsm
    )
    ->getResult();

Das Ergebnisarray sieht so aus:

Array
(
    [0] => Array
        (
            [date] => 2013-01-05
            [rating] => 1
            [count] => 8
        )

    [1] => Array
        (
            [date] => 2013-01-05
            [rating] => 2
            [count] => 4
        )

    [2] => Array
        (
            [date] => 2013-01-05
            [rating] => 3
            [count] => 1
        )

    [3] => Array
        (
            [date] => 2013-01-07
            [rating] => 1
            [count] => 22
        )
...
)

Damit kann man nun prima weiterarbeiten. Zu beachten ist, dass in der Query die Originalnamen der Spalten aus der Datenbank genutzt werden müssen und nicht die Namen der gemappten Attribute aus der Entität. Dazu gibt es auch eine Abhilfe, die in der Doctrine-Dokumentation zur NativeQuery erklärt wird.