XRumer knackt reCaptcha

07 03 2011

Scheiß SPAM-Arschgeigen, die ihr Geschäft vornehm Blackhat-SEO nennen. Ekelerregendes Pack. Seit einiger Zeit bekomme ich täglich ein bis zwei Spamkommentare hier im Blog, die es offenbar an meinem reCaptcha vorbei schaffen. Die bekommt ihr nicht zu sehen, weil sie allesamt in der Moderierungsfunktion hängen bleiben, wenigstens das funktioniert. Meine erste Befürchtung hat sich aber leider bewahrheitet: SPAM-Tools können reCaptcha knacken. Ein Spamkommentar brachte mich auf die richtige Fährte, ein Tool mit dem Namen XRumer wird in grauen Kanälen verkauft und wirbt ganz unverhohlen mit reCaptcha-Knack-Fähigkeiten:

With XRumer Elite will be possible to pass automatically such popular protections as ReCaptcha and DLE-captcha (ReCaptcha is used on more than 30% of resources; same as DLE-captcha become very popular). XRumer Elite can bypass 7 new most popular graphical protections.

Die Software kostet 570€ und es bedarf einer gewissen Planung, um damit erfolgreich Suchmaschinen-SPAM platzieren zu können. Was aber bedeutet das für mein Blog und seine Kommentarfunktion? reCaptcha als das einzig erfolgversprechende grafische Captcha fällt also aus, noch stärkere, mithin also auch noch schlechter lesbare Captchas kommen keinesfalls in die Tüte. Andererseits regnet es ganz ohne Captcha noch viel mehr Spamkommentare. Dass Kommentare moderiert werden, also nie öffentlich erscheinen, nimmt mich offenbar nicht aus der Opferliste und macht mir nicht ganz wenig Arbeit.

Nun bestünde die Möglichkeit, Kommentare in meinem Blog ganz abzuschalten, was gemessen am Verhältnis von Kommentaren zu Einträgen sogar verschmerzbar wäre (ich habe weniger Kommentare als Beiträge und lege auch keinen Wert auf Kommentare). Aber ein Blog ohne Kommentarfunktion ist irgendwie kein Blog und außerdem wäre das eine Kapitulation vor dem Spammer an sich, dafür bin ich noch zu stolz. Ich werde also vorerst weiter die Moderations-Benachrichtigungsmails ignorieren und abwarten, was sich an der Front tut.

Scheiß SPAM-Arschgeigen, die ihr Geschäft vornehm Blackhat-SEO nennen. Ekelerregendes Pack.


Standortdaten im Browser auf stationären Computern

12 02 2011

Jaja, irgendwann ist alles mobil und wireless und in der Cloud, aber bis dahin benutzen wir noch ab und an bis immer stationäre Computer, die an Kabeln hängen. Die meisten modernen Desktopbrowser (auch der IE ab Version 9) unterstützen die Abfrage von Standortinformationen durch Websites, etwa um bequem die nächste Filiale von Laden X zu finden oder sich bei Foursquare einzuchecken. Das ist schön und mit Notebooks funktioniert wohl das dank WLAN-Erkennung auch ohne GPS überraschend gut. Auf Computern ohne WLAN wird aber lediglich die IP-Adresse zur Erkennung des Ortes herangezogen, was die Genauigkeit auf irgendwo zwischen Stadtmitte der aktuellen Stadt und Langen in Hessen drückt, mithin also zum einen reichlich nutzlos ist, zum anderen aber auch Serverseitig anhand der IP-Adresse gemacht werden kann, ganz ohne Mitwirkung des Besuchers.

Da sich Geräte ohne WLAN in der Regel nur an einem Ort aufhalten, wäre es nun konsequent, wenn man im Browser einmal seine Position festlegt und fortan eine richtige Positionsangabe hat. Doch weit gefehlt. Weder Opera 11, noch Firefox 3.6 oder Chrome 9 bieten eine Möglichkeit, seinen aktuellen Ort manuell einzustellen, es wird einfach alternativlos der auf der IP-Adresse basierende Dienst von Google benutzt. Für den Firefox gibt es immerhin ein Add-On namens Geolocater für genau diesen Zweck, aber sowas gehört direkt in den Browser. Ich frage mich ernsthaft, wieso kein Browserhersteller es für nötig hält, dass ein Nutzer seine gemeldete Position manuell festlegen kann. Hat da jemand eine Antwort?


HTML5-Elemente auch im IE ohne JavaScript und trotzdem valide

20 12 2010

Ha, na sowas. Da kommt jemand mit einer relativ eleganten Möglichkeit um die Ecke, dem IE die neuen HTML5-Elemente auch ohne JavaScript bekannt zu machen. Er benutzt dafür einen XML-Namespace und benutzt dann so Sachen wie html5:section statt section. Das ist geradezu genial und funktioniert angeblich sogar zuverlässig, validiert aber in erster Linie nicht, wenn man sich nicht mit XHTML5 ganz anderen Ärger ins Haus holen will. Daneben ist es auch komisch, wenn der Autor so ein HTML schreiben muss, nur um auf den IE Rücksicht zu nehmen. Wie ließe sich das also noch verbessern?

Mir kam sofort die naheliegende Idee, das mit einem serverseitigen Ausgabefilter nur an die IEs auszuliefern. Die Voraussetzung wird nicht jedes CMS einfach so mitmachen, aber falls doch, ermöglicht einem das, die HTML5-Elemente jetzt zu benutzen. Wie genau soll das funktionieren? Wenn man einen serverseitigen DOM/HTML-Parser benutzt, ist es relativ leicht, aber das sollte in der CMS-Landschaft die große Ausnahme sein. Also braucht man ein paar simple RegExes:

  • <html muss im HTML-Output durch <html xmlns="http://www.w3.org/1999/xhtml" xmlns:html5="http://www.w3.org/1999/xhtml" ersetzt werden. Wenn man gründlich arbeitet, prüft man vorher, ob das HTML-Element nicht schon die passenden Namespaces trägt.
  • <(/?)(abbr|article|aside|audio|canvas|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video) muss im HTML-Code durch <$1html5:$2 ersetzt werden, das sind die öffnenden und schließenden Tags.
  • (abbr|article|aside|audio|canvas|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video) muss im CSS durch html5\:$1 ersetzt werden.

Das schöne an dieser Lösung ist, dass man Serverseitig recht einfach einen IE erkennen kann und ihm die gefilterten Quellen anbietet. Dass der Code für den IE nicht validiert, halte ich für verschmerzbar. Falls man versehentlich einen Browser erwischt, der sich nur als IE ausgibt, klappt zudem trotzdem alles. Und das wichtigste in meinen Augen ist, dass man die CSS Spezifität nicht verändert und sich auf diesem Weg keine Seiteneffekte ins Boot holt. Gut so.

Der einzige Nachteil, den ich momentan sehe, ist die Voraussetzung eines finalen Output-Filters. Viele CMSe buffern den HTML-Output sowieso und bieten einen Hook an, an den man sich einfach dranhängt, in dem Fall hat man natürlich leichtes Spiel. Etwas schwieriger ist das bei CMSen, die sowas nicht haben und vor allem bei statischen CSS-Dateien, in dem Fall muss man irgendwie einen Filter in den Workflow frickeln, was stark von der eingesetzen Serverumgebung abhängt und nicht einfach generalisiert lösbar sein wird. Wenn man aber sowieso schon ein CSS-Framework wie Turbine einsetzt, lässt sich das prima dort lösen, vielleicht gar mit einem HTML5-Enabler Plugin. Ansonsten wäre das mal ein guter Anlass, so ein Framework einzusetzen.

Damit löst man aber noch immer nicht das Cache-Problem: Man muss externe Proxy-Caches aushebeln und benötigt zudem plötzlich zwei lokale Caches, die von der Cache-Logik unterschieden werden müssen. Da wird es dann diffizil und man verzichtet vielleicht lieber auf eine Browser-Unterscheidung, macht den Output-Filter immer an und scheißt auf den Validator. Ist ja auch eine Lösung und man muss weiterhin nicht selbst mit den Namespaces hantieren.


Terminfindungswebdienst

28 11 2010

Seit ein paar Jahren veranstalte ich mit ein paar Kollegen in unregelmäßigem Abstand einen kleinen Jour-Fixe, die Terminabsprache findet in einer Mailingliste statt. Die Erfahrung damit zeigt, dass das schon bei 6 Leuten unübersichtlich wird und eine klare Diskussion für Alternativtermine nicht ganz leicht ist. Nun kommt noch ein mehr oder weniger regelmäßiger Spieleabend dazu, an dem auch noch Leute teilnehmen werden, denen ich die korrekte Bedienung einer Mailingliste gar nicht erst zutraue. Es muss also eine alternative technische Unterstützung hinzukommen. Spontan fällt mir da nur Doodle ein, aber deren tabellenartiges System geht mir nicht weit genug, weil es die komplexen Zusammenhänge von Zusagen nicht abbilden kann. Dass man mehrere Daten zur Wahl hat und nur entweder sagen kann, ob man kann oder nicht, reicht eben nicht. Also überlege ich, sowas schnell mal selbst zu schreiben. Aber was braucht es für ein Featureset? Nach ein wenig Nachdenken bin ich auf folgende Funktionen gestoßen:

  • Es muss geschlossene Gruppen geben, die per E-Mail abonnierbar sind. Neue Terminvorschläge (mit oder ohne Alternativen) und Änderungen gehen als Benachrichtigung raus, ein Klick auf einen Link in der Mail sollte dabei direkt einen Status setzen können, ohne, dass man sich extra einloggen muss. Es sollte zudem auch offene Gruppen/Events mit und ohne Einladung geben.
  • Bei mehreren Terminvorschlägen für ein Event muss es eine intuitive Priorisierung geben, vielleicht per Drag and Drop, vielleicht anders. Man muss ausdrücken können, dass einem Termin A lieber als Termin B ist, man aber bei Termin C gar nicht kann. Zudem muss unterschieden werden zwischen benachrichtigt, aber nicht reagiert und einer expliziten Ablehnung.
  • Es muss eine Möglichkeit geben, vielleicht bzw. unter Vorbehalt zuzusagen. Daraus ergibt sich auch die Anforderung, dass es einen leicht zugänglichen Kommentar zu jedem eigenen Voting geben muss. So ein Kommentar sollte nicht chronologisch aufgeführt werden, sondern als Metainformation zum Voting.
  • Man muss seine Votings ändern können, ein Zeitstempel für die letzte Änderung muss dabei veröffentlicht werden. Außerdem sollten Events auch vor ihrem eigentlichen Datum als abgeschlossen markiert werden können.
  • Es sollte die Möglichkeit geben, dass der Eventbesitzer bestimmte oder alle Personen als "Muss dabei sein" oder "Wäre schon wichtig" markieren kann. Zudem sollte er den Usern der Gruppe freistellen können, solche Bedingungen für sich (und ggf. auch andere) zu definieren.
  • Es sollte einen Kommentarbereich geben, wo kurze Diskussionen ausgetragen werden können (etwa "Was essen wir?).
  • Die Votingtabelle sollte via iFrame anderswo einbindbar sein.
  • Die Softwarebasis sollte unter einer Open-Source-Lizenz veröffentlicht werden, so dass jedermann so ein System für sich aufsetzen kann. Möglicherweise kann man sowas auch als Cloud-Dienst für andere anbieten.
  • Es muss eine API (mindestens JSON) geben, über die der Dienst (wahlweise) auch von Außen bedienbar wird. Authentifizierung könnte per oAuth gemacht werden, standardmäßig aber per Cookie und bei Mails via Token. Sicherheit bei der Authentifizierung sollte im Zweifel gegenüber Komfort bei der Nutzung nachrangig behandelt werden.
  • Die Oberfläche sollte optisch angenehm sein und sich mit ausgeprägter AJAX-Unterstützung flüssig bedienen lassen. Ein Fallback mit Mindeststandard für Nutzer ohne JavaScript könnte implementiert werden, aber es dürfen dadurch keinerlei Komforteinbußen bei Nutzern mit JavaScript entstehen. Der Internet Explorer 6 (und ggf. auch 7) wird als Browser nicht berücksichtigt, solche Nutzer werden entweder gewarnt (und können es dann wenigstens mal versuchen) oder sofort abgewiesen. Ausnahme: Der Request wird trotzdem ausgeführt, klicks auf Links in Benachrichtigungsmails müssen immer funktionieren. Technisch wird auf CSS3 und HTML5 gesetzt, als JavaScript-Framework kommt jQuery zum Einsatz, serverseitig basiert das System auf PHP 5.3 (und MySQL oder SQLite via PDO) und ggf. auf einem Framework (Symfony, Zend, Flow3). Gegen ein Framework spricht, dass man das System ggf. kapseln könnte, um es als PlugIn für verschiedene CMSe zu portieren. So komplex sollte das nicht sein und das MVC-Paradigma und andere Design-Patterns kann man auch so nutzen. Der Login-Mechanismus (samt Gruppen- und Userverwaltung), der Dispatcher (für das Routing der Requests und vor allem der API) und das Model müssten dann modular aufgebaut und austauschbar sein, die Output-Templates sind es ja sowieso schon.
  • Ggf. könnte das System nicht nur für Events genutzt werden, sondern auch für die allgemeine Entscheidungsfindung. Man stellt also etwa Pizza, Asia, Pommesbude, Döner und Nudeln zur Wahl und bekommt am Ende eine Entscheidung mit dem besten Kompromiss. Da wird besonders deutlich, wie wichtig eine Einstufung jenseits von ja und nein ist.

Habe ich eine wichtige Funktion vergessen? Gibt es Input? Meldet Euch einfach bei mir, aber denkt daran, dass ich kein ICQ mehr benutze.


Ist Joomla ein Hort für Stümper?

05 10 2010

Vorweg: Ich habe mal im Jahr 2005 für ein Projekt einen genaueren Blick in das CMS Joomla geworfen und mich klar dagegen entschieden. Ich weiß nicht mehr im einzelnen, wieso, aber die Entscheidung war sehr klar und fiel seinerzeit zugunsten von TYPO3 aus, das ich seitdem hervorragend bewährt hat. Ich weiß also im Grunde nicht viel über Joomla. Irgendwann habe ich mal beim Multimediatreff in Köln einen Vortrag zur Joomla-Entwicklung gehört, bei dem der (oder die?) Vortragende keinen leichten Stand hatte: Das Publikum war offensichtlich der Meinung, dass Joomla eher zu den weniger ernstzunehmenden Content-Maganement-Systemen gehört; zudem überzeugte auch der Vortrag kaum vom Gegenteil. Auch sonst haben Joomla-Integratoren einen schweren Stand in meiner Peergroup. Genau genommen habe ich nicht eine Empfehlung für Joomla von jemandem gesehen, den ich in Sachen Webentwicklung üblicherweise ernst nehme. Vielleicht ist das Zufall, aber ich kenne auch niemanden, der jemanden kennt, der Joomla einsetzt und dabei – wie auch immer definiert – gut ist.

Wo mir Joomla aber häufig begegnet, ist bei sehr günstigen Angeboten für Webseiten (sowohl Wettbewerb für, als auch zur beratenden Prüfung durch mich). Fast immer sind das 1-Mann-Agenturen, deren Angebote und vor allem deren Auftreten mich nicht von gesteigerter technischer Kompetenz überzeugt. Ganz häufig sind das Quereinsteiger, die sich autodidaktisch irgendwie HTML und CSS angefressen und im Zuge der Joomla-Integration auch ein paar Brocken sehr schlechtes PHP angeeignet haben. Ich möchte das nicht generell kritisieren, jeder fängt mal an und lernt den Kram im Laufe der Zeit irgendwie mehr oder weniger gut. Das Problem ist, dass bei den Leuten, die mir im Joomla-Kontext begegnet sind, das weniger dominiert. Das heißt nicht, dass jeder Joomla-Integrator ein Stümper ist; nur eben, dass er sich in einem Umfeld mit auffällig vielen Stümpern bewegt.

Frage ist: Warum ist das so? Ist Joomla ein schlechtes CMS? Meiner Meinung nach ja, aber das ist wenig objektiv. Aber irgendwas muss doch da dran sein, wenn es so beliebt ist. Module zusammenstöpseln und eine irgendwie lauffähige Seite bekommen, ohne sich groß einarbetien zu müssen, können auch andere Systeme. Was ist es also, was all die Stümper und Anfänger so anzieht? Warum setzt man ein System ein, dessen nach vielen Jahren endlich erscheinende neue Version ungefähr das halbe Featureset von anderen Systemen vor fünf Jahren implementiert? Stichwort Rechtesystem oder tabellenfreier HTML-Output der Core-Funktionen. Weil es so einfach in der Integration ist und man vom Wissensstand her nicht in der Lage ist, ein besseres System einzusetzen? Dann stellt sich aber die Frage: Warum nimmt man Geld für eine Dienstleistung, wenn der eigene Wissensstand gerade mal für das einfachste Werkzeug reicht? Immerhin muss man den Joomla-Integratoren der Kreisliga lassen, dass sie meistens auch nur Kreisliga-Preise aufrufen. Wenn ich aber bei günstigen Nebenberuflern die Wahl habe zwischen einem ambitionierten Studenten und einem Feierabend-Joomla-Bastler, gewinnt der ambitionierte Student. Joomla im Angebot ist für mich ein klar schlechtes Zeichen, das würde ich nicht buchen. Gemeine Vorurteile? Vielleicht, aber auch das ist bei der Wahl eines CMS für Angebote für Geld zu berücksichtigen.

Aber mit der nächsten Version kommen doch endlich alle wichtigen Features… Ja, schön. Schon mal die Planungen für TYPO3 5.0 gesehen? Nein? Weil das noch nicht relevant ist, weil es in ferner Zukunft passiert? Genau. Handfeste Defizite in der aktuellen Version mit Planungen für die Zukunft zu entschuldigen, ist nicht zielführend, weil die anderen sich ebenfalls weiterentwickeln. Während in Villabajo noch mit einem benutzbaren Rechtesystem gekämpft wird, redet man in Villarriba von Aspektorientierter Programmierung, MVC, Content-Repositories und (vielleicht endlich mal praxistauglichem) Frontend-Editing.

Empfehlungen, die ich übrigens über die Jahre immer wieder gehört habe, sind ModX (das als Geheimtipp gilt), TYPO3 (das ich selber häufig nutze), Wordpress (weil alle es nutzen, es ein tolles Backend hat und es so schön nah am Code operiert), Textpattern (das ich vom Konzept her gar nicht mochte, das aber von seinen Fans vehement vertreten wird), Drupal (vor allem im Community-Kontext) und verschiedene kleinere recht charmante Systeme.


Please put the C in CSS

24 09 2010

Fast immer, wenn ich an Websites arbeite, die andere (Agenturen) verbrochen haben, stolpere ich über mehr oder weniger lästige Eigenheiten der konkreten Implementierung. Dass man TYPO3 auf etliche verschiedene Weisen mit Templates füttern kann, ist ja normal, auch dass es Abweichungen in der Sorgfalt im Umgang mit HTML-Markup und CSS-Code gibt. Aber es gibt Abweichungen im Rahmen des Nachvollziehbaren und solche, die einfach dumm, lästig und ärgerlich sind.

Aktuelles Beispiel: Ich mache zur Zeit einige inhaltliche Änderungen an einer Website, deren CSS-Code sehr eigenartig ist. Die auffälligste Eigenart ist dabei wirklich spaßig: Man hat dem BODY ein text-align: center; gegeben, ohne das bei nächster Gelegenheit, etwa einem Wrapper, wieder zurückzunehmen. Nun könnte einem im weiteren Verlauf auffallen, dass nun alles, aber wirklich alles zentriert wird. Das ist natürlich nicht zu übersehen und vor allem ziemlich lästig. Ich und die meisten anderen Frontend-Entwickler, die ich kenne, würden nun unseren Fehler bemerken und dem Wrapper ein text-align: left; zuweisen, wie es best practice ist. Nicht so der Entwickler dieser Website, denn der gibt der mittleren Content-Box diese Eigenschaft und zudem noch mal allen möglichen anderen Boxen, die nicht zentrieren sollen. Bei der Gelegenheit habe ich mal die style.css geöffnet und staunte nicht schlecht: Fast alle vergebenen Styles sind per ID an verschiedene Content-Boxen drangehängt, so dass beispielsweise eine H2 in Box A gestyled ist, in Box B, C und D und überhaupt anderswo nicht; was wiederum bedeutet, dass sie fast überall zentriert ist (und sonst die Standardeigenschaften des Browsers für H2 hat). Das ist eine Wartungshölle sondergleichen, denn bei jeder Inhaltsänderung, die über den initialen Zustand der Site hinausgeht, muss man den Style anfassen. Letztlich hat man also etwas ähnliches, wie inline-styles, nur eben in eine externe Datei ausgelagert und auf unvorhersehbare Weise mal wirkungsvoll und mal nicht. Die Vorteile der Kaskadierung werden also nicht ausgespielt, die Nachteile aber schon.

Nun wäre es eine Kleinigkeit, das alles zu korrigieren, aber dann schlägt gnadenlos der Nachteil der Kaskadierung zu: Man weiß nicht, welche Seiteneffekte sich bei grundlegenden Änderungen ergeben. Nimmt man etwa die Zentrierung für alles heraus, wird man gar nichts mehr zentriert vorfinden, weil bei absichtlich zentrierten Elementen möglicherweise eine Angabe zur Zentrierung weggelassen wurde, weil sich das ja implizit aus der nicht zurückgestellten Zentrierung des BODYs ergibt. Ohne eine genaue Analyse des Stylesheets und der Seitenstruktur, sowie umfangreiche Tests wird man solche Änderungen also besser nicht machen. Ich halte mich in solchen Fällen einfach an das vorgegebene System und ergänze meine nötigen Styles entsprechend. Das macht es nicht besser, aber wenigstens wird man – ohne daran Schuld zu sein – für jede dieser Änderungen angerufen und bezahlt.

Die ahnungs- oder lustlose CSS-Schluderei ist nur ein Aspekt dieser Website, auch die URLs der Seiten (mit CoolURI gemacht) waren weit entfernt von Sinn und Zweck einer guten URL-Struktur. Die Menüs sind lieblos zusammenkopiert, das Hauptmenü ein manuell erstelltes (und manuell zu pflegendes) Imagemap-Ungetüm, das einen besonders spannenden Nebeneffekt zeigt: Sind Seiten in TYPO3 nicht über zumindest irgendein automatisch erstelltes Menü zu erreichen, kann CoolURI die URL der Seite nicht wissen und wirft eine Fehlerseite. Man muss nun für jede dieser Seiten einen manuellen Eintrag in CoolURI vornehmen und den bei Änderungen auch Pflegen. Besonders lustig ist das, wenn man die URL-Struktur nach umfangreichen Änderungen neu startet und dann das Hauptmenü nicht funktioniert. Falls man eine automatische Sitemap hat, kann die einen immerhin retten. hat man hier aber nicht. Solche Schludrigkeit zieht sich durch das gesamte Projekt und macht erhebliche Mehrarbeit bei der Pflege. Kein Wunder, dass direkt nach Projektabschluss alle Passwörter geändert wurden und die Änderungen bei mir landen. Leider ist das kein Einzelfall, gerade im TYPO3-Kontext treffe ich immer wieder auf haarsträubende Implementierungen. Ob die Agenturen, die immerhin explizit TYPO3 anbieten, zu dumm oder zu faul sind, weiß ich nicht.

Also aufgemerkt: Wenn man jemanden beauftragt, eine Website umzusetzen, gerade bei TYPO3 und anderen komplexen Systemen, achte man auf einen Dienstleister mit Ahnung und Bock. Nur billig billig schnell schnell führt einen zu oft schon mittelfristig aufs Wartungs-Glatteis. Mir ist das recht, wenn ich der Typ bin, der jammern darf und dabei auch noch gut an der Schludrigkeit anderer verdient.


Objektorientierte Entwicklung vs. PHP 4

05 05 2010

Zur Zeit arbeite ich an einem Wordpress-Projekt und bin nach der Umstellung auf PHP 5.3 (vorher war versehentlich PHP 4 auf dem Webspace aktiv) über etliche Deprecated-Warnungen gestolpert. Die explizite Zuweisung von Objekten per Referenz (also mit =& statt dass das Objekt mit = geklont wird) in der wp-settings.php ist schuld, denn dieses im Grunde erwartungskonforme Verhalten ist seit PHP 5 der Normalfall, Objekte werden jetzt nur noch geklont, wenn man explizit clone benutzt, so dass die explizite Zuweisung per Referenz überflüssig ist und angemahnt wird.

Nun ist es bei einem guten Hoster ein Handgriff ein, die E_DEPRECATED-Warnungen in der php.ini zu unterdrücken, von daher ist das alles halb so wild. Die Sache ist aber ein Symptom eines großen Dilemmas: Will man – aus welchen Gründen auch immer – kompatibel zu PHP 4 bleiben, muss man manchmal Code schreiben, der in PHP ab 5.3 eine Deprecated-Warnung wirft. Das TYPO3-Backend beispielsweise warf bis vor kurzem (vielleicht auch immer noch) ebenfalls Unmengen an Deprecated-Warnungen, weil es intensiven Gebrauch von eregi-Funktionen macht. Die kann man mit gutem Geschwindigkeitsgewinn und ohne Schwierigkeiten mit PHP 4 gegen preg-Funktionen austauschen, hier ist es also lediglich eine Sache von Fleiß; ganz davon abgesehen, dass TYPO3 sowieso seit Jahren kein PHP 4 mehr unterstützt. Die Sache bei Wordpress und einigen anderen Projekten mit Objektorientierten Elementen ist aber eine Zwickmühle.

Wobei es in meinen Augen keineswegs eine Zwickmühle ist, da die Lösung auf der Hand liegt: Man wirft einfach den PHP 4 Support über Bord und hält die Anfeindungen einiger Ewiggestriger aus, die nicht wissen, wie sie bei ihren Webspace eine aktuelle PHP-Version umstellt. Diese Anfeindungen kommen leider vor, und sind einer der Gründe, wieso ich zu Serendipity keinen Code mehr beitrage. Serendipity bewahrt wie Wordpress noch immer die PHP 4 Kompatibilität und steht einer zukunftsgerichteten Weiterentwicklung damit massiv im Weg. Wordpress wird wohl ab Version 3.0 (also ab demnächst) PHP 5 vorraussetzen, damit es endlich nach vorne gehen kann. Das ist im Falle von Wordpress auch bitter nötig, wenn man sich den mitunter grauenerregenden Code anguckt. Die aktuelle Beta 1 wirft aber leider immer noch die Deprecated-Warnungen.

Es gibt so etwas wie Codehygiene. Ich frage mich, wieso sich so viele Softwareprojekte mit aller Macht dagegen stemmen, ihren Code ein wenig zu warten. Eregi-Funktionen gelten schon seit mindestens fünf Jahren als um Größenordnungen langsamer, als ihre preg-Pendants. Wieso zur Hölle liest man dann als Abhilfe für Deprecated-Meldungen immer und überall, dass man die Warnungen ausschalten soll? Wo ist das Problem, sich einmal eine Nacht hinzusetzen und die veralteten und langsamen eregi-Funktionen zu eliminieren? Wieso wird unter Verzicht auf fundamental wichtige Programmiertechniken der Objektorientierung auch mehrere Jahre nach Einstellung des Supports für PHP 4 so sehr daran geklebt? PHP 4 ist veraltet, langsam und behindert massivst eine saubere Programmierung. Das ist sogar so offensichtlich, dass es jedem auffallen müsste, der nur ansatzweise objektorientiert mit PHP programmiert. PHP 4 fehlt es an fundamentalen Funktionalitäten an allen Ecken und Enden, nicht nur bei der Objektorientierung. Bitte, hört auf mit der falsch verstandenen Rückwärtskompatibilität und blickt mal nach vorne.

P.S. Ich bin übrigens latent auf der Suche nach einem neuen Blogsystem. Serendipity möchte ich den Rücken kehren, weil sich an der Front scheinbar nichts mehr tun wird. Auf PHP 5 umstellen? Neue Programmierkonzepte zulassen? Nix da, alles bleibt, wie es ist. Ein System, dessen Core so ungerne angefasst wird, ist nicht meins. Davon abgesehen, dass der Core in meinen Augen sowieso gar kein HTML ausgeben sollte. S9Y ist super stabil und funktioniert bei mir seit nunmehr fast sechs Jahren ohne jedes nennenswerte Problem vor sich hin, aber in etwa so lange hat sich auch nicht mehr wirklich etwas nennenswertes weiter entwickelt; das stimmt zwar nicht ganz, aber die Änderungen blieben insgesamt doch sehr dezent. Wordpress ist leider keine Alternative, auch wenn das Backend großartig ist. Ein Blick in den Core an beliebiger Stelle sollte ausreichend Anlass geben, das System nicht zu wollen. Was ist eigentlich aus Habari geworden?


Wordpress macht jQuery-Code in Posts kaputt

29 04 2010

Heute musste ich in einem Wordpress-Eintrag ein kleines jQuery Script einbauen, wofür ich erst mal ein DIV an den BODY anhängen musste. Im Grunde macht man sowas in jQuery mit folgendem Code:

<script>
  jQuery('<div id="soundso" class="undsoso"></div>').appendTo('body');
</script>

Leider fährt einem Wordpress hier an die Karre, wenn man das in den Post-Editor einfügt (davon abgesehen, dass sowieso alles kaputt ist, wenn man den WYSIWTFWYSIWYG-Editor benutzt). Die Automatik, die Ps um die Absätze macht, grätscht hier rein und fummelt da irgendwie noch ein p mit rein, wo es einem einen JavaScript-Fehler einbringt. Eine andere Weise, dieses DIV zu erzeugen, scheiterte an anderen Randbedingungen oder wäre sehr unelegant gewesen, deswegen musste ich das irgendwie hinbekommen. Da Wordpress normalen JavaScript-Code in Frieden lässt, habe ich letztlich auf die Standard-JavaScript-Methode zurückgegriffen, wie man DOM-Elemente erzeugt. Das sieht dann so aus:

<script>
  var d = document.createElement('div');
  d.id = 'soundso';
  d.className = 'undsoso';
  document.body.appendChild(d);
</script>

Wenn man es so macht, lässt Wordpress den Code passieren, ohne daran wohlmeinend herumzufummeln. Eine andere Möglichkeit ist das PlugIn Text Control, das auf Pro-Post-Basis die Textformatierungen abschalten kann. Das Plugin scheint auf den ersten Blick trotz des Alters (es ist von 2005) mit einem aktuellen Wordpress zu funktionieren, aber leider bietet es seine Dienste nur für Posts an und nicht für statische Seiten.

Nachtrag 06.05.2010: Man kann auch einfach radikal wie wpautop-Funktion deaktivieren, etwa mit diesem PlugIn. Das automatische rein pfriemeln von Absätzen ist nett gemeint, aber es schadet in der Praxis mehr, als es nützt; zumindest in meiner Praxis.


Wie man Short-URLs und so verüberflüssigen kann

27 07 2009

Der Microblogging-Server laconi.ca kann jetzt auch Dateianhänge. Das ist nett und macht Twitpic und Co. langfristig überflüssig. Dateiuploads funktionieren sehr simpel: Man lädt eine Datei hoch, der Dienst generiert dazu eine Short-URL mit is.gd. und fügt diese am Ende des Dents ein. Das wars. Dabei hätte man es wahrscheinlich so viel besser machen können.

Im Prinzip ist das Problem mit Dateianhängen das gleiche, wie mit URLs allgemein und verschiedenen anderen Sachen: Sie sind im Grunde Metainformationen zur Nachricht selbst und kollidieren mit dem 140 Zeichen Reintext-Limit beim Microblogging. Das ist etwas unfair, denn URLs sind mitunter sehr lang, gelegentlich sogar länger als 140 Zeichen. Abhilfe schaffen die vielen Short-URL Dienste, aber nun weiß man zum einen nicht mehr, was sich hinter einem solchen Link verbirgt (wie bei dem hier), zum anderen können Dienste schließen und alle darüber generierten URLs würden unbrauchbar werden. Oder aber URLs werden nach einiger Zeit recycelt, was noch schlimmer ist, denn nun zeigt mein Link auf eine völlig andere Seite. Short-URLs sind also scheiße und zu vermeiden, wo es nur geht. Doch wie? Im Folgenden ein paar Lösungsansätze zum Thema.

Wie wäre es, wenn Twitter (stellvertretend für alle Microblogging-Dienste gemeint), eine URL pro Nachricht als Metaangabe erlaubt. Die einfachste Möglichkeit dazu wäre es, von URLs nur ein Zeichen bei der 140-Zeichen Limitierung zu berücksichtigen. Das hätte aber gleich zwei gravierende Seiteneffekte: Erstens bricht man die API, denn viele Dienste erwarten nur 140 Zeichen und würden die Nachricht deswegen einfach abschneiden. Zweitens würde sich schnell die Unart etablieren, ganze Sätze in nicht existierenden URLs zu formulieren und so das Limit zu umgehen. Diese Möglichkeit kommt also keinesfalls infrage.

Eine erste echte Möglichkeit wäre es, wenn Twitter von jeder Short-URL beim entgegennehmen des Tweets das Ziel auslesen würde und dieses Ziel zur Verlinkung (oder als Title-Attribut) in der geparsten Nachricht benutzen würde. In der Textversion (über die API) würde dann aber immer noch alleine die Short-URL stehen, Twitter-Clients, die diese selber parsen, bekämen also davon nichts mit. Zudem werden die URL-Shortener das gar nicht mögen, werden sie so doch brutal übergangen. Das grundsätzliche Problem bliebe bei der Lösung außerdem bestehen: Die Short-URL ist immer noch da, wird archiviert und man ist weiterhin dem URL-Shortener ausgeliefert. Vorteilhaft wäre, dass Twitter das Verfahren sofort einführen könnte und die volle Kontrolle darüber hätte. Sprich: User könnten das Verhalten konfigurieren, wenn sie es nicht mögen und Twitter kann sich aussuchen, bei welchen URL-Shortenern sie das Verfahren anwenden. Denkbar wäre auch, dass Twitter einen eigenen URL-Shortener Dienst anbietet, der das Verfahren implementiert.

Meine eigentliche Idee ist aber Folgende: Twitter erweitert seine API um ein Feld für eine URL (mit max 255 Zeichen). Das Webinterface und Twitter-Clients, die das Verfahren implementiert haben, bieten ein extra Eingabefeld für diese URL und fügen (zumindest übergangsweise) automatisch eine Short-URL dazu in die Nachricht ein. Diese Short-URL wird zweckmäßigerweise von einem dem Dienst angeschlossenen Service bereitgestellt und sollte garantiert so lange leben, wie es den Dienst gibt. Ältere Clients schicken eine normale Short-URL in der Nachricht und Twitter parst diese (bzw. die erste, wenn es mehrere gibt) und füllt die eigentliche URL in das Extrafeld ein. Als einzigen Nachteil des Verfahrens sehe ich, dass durch die Erweiterung der API das Verfahren nicht sofort in voller Schönheit in allen Clients zum Vorschein kommt. Dass so nur eine solche URL pro Nachricht möglich ist, sehe ich angesichts des 140 Zeichen Limits als durchaus konsequent und nicht als Nachteil an. Langfristig sehe ich aber große Vorteile in dem Verfahren: Es ist voll abwärtskompatibel, bringt aber neue Möglichkeiten mit. Können genug Twitter-Clients mit diesen URLs angemessen umgehen, kann man auf das Einfgen einer zusätzlichen Short-URL verzichten und hat die vollen 140 Zeichen für seine Nachricht zur Verfügung. Ein weiterer Vorteil ist, dass die Clients selbst entscheiden können, wie sie mit URLs umgehen wollen.

Ich halte das für eine saubere Lösung für das leidige Short-URL Problem, aber eben auch für andere Metadaten. Dateianhänge könnten auf die gleiche Weise implementiert werden, intern macht laconi.ca/identi.ca das offenbar ja schon so. Nur hapert es eben an der Anbindung nach Außen. Ebenfalls abgefrühstückt werden könnte dann endlich auch mal eine sinnvolle und nicht störende Geokodierung von Beiträgen. Momentan behilft man sich mit Krücken wie L:Düsseldorf, was für "Location Düsseldorf" steht, oder der sehr hässlichen Einbindung von Geokoordinaten direkt in den Nachrichtentext. Ein Metafeld für Geoinformationen würde hingegen niemanden stören, eine verlässliche Einbindung von Kartendiensten in geofähigen Clients erlauben und so schöne Geschichten wie Live-Twitter-Maps ermöglichen. Flickr hat das so schön vorgemacht.

Mancher mag jetzt einwenden, dass gerade die Einfachheit von Twitter mit dem einen Eingabefeld seinen Charme ausmacht. Dem halte ich entgegen, dass drei kleine Knöpfchen neben dem Eingabefeld für diese Metainformationen der Einfachheit keinen Abbruch tun würden, die vielen Twitter Poweruser hätten aner eine schöne Möglichkeit, ihre Tweets sauber zu halten. Kein Anfänger auf der Suche nach Einfachheit versteht Tweets, wo alles irgendwie verlinkt ist mit #Tags, !Gruppen, L:Orten, http://sho.rt/urls, RTs und @namensnennungen. Da kann man doch beim besten Willen nicht mehr von Einfachheit sprechen und eine Metaangabe für Reply-Tos gibt es schon immer und jeder weiß die zu schätzen.

Meine Forderung an Twitter und identi.ca lautet also: Erweitert Eure API um Felder für eine URL, Geokoordinaten und ggf. einen Dateianhang. Die Leute benutzen diese Sachen tagtäglich und nutzen dafür teilweise ärgerliche Krücken. Schluss damit!

Ich selber werde bei Gelegenheit meine PHP-Twitter-API derart erweitern, dass sie eingehende Short-URLs auflöst und ersetzt (und das Ergebnis cached). Profitieren wird davon mein Lifestream und die Microblog-Anzeige in der Sidebar vom Blog.

Nachtrag 24.08.2009: Inzwischen hat Twitter eine Erweiterung um Geokoordinaten zu jedem Tweet angekündigt, was gut ist. Was aber schlimmer als gedacht ist: Twitter kürzt automatisch und unabschaltbar alle URLs mit mehr als 30 Zeichen mit bit.ly. Ich hasse das, denn wenn ich von meinen 140 Zeichen 60 für eine URL opfere, dann hat das seinen Grund. Hoffentlich ändert sich das irgendwann mal wieder.


Mal wieder: Wie sollte man mit den IE6-Nutzern umgehen?

15 07 2009

So viel wurde schon zum IE6 geschrieben, so viel Hass wurde ausgeschüttet und so viele Erklärungsansätze für den noch immer beschämend hohen Marktanteil dieses Fossils wurden gebracht. Nun muss ich noch mal etwas dazu loswerden. Warum gerade jetzt? Zu einen habe ich zuletzt mehrere Tage unbezahlt mit IE6-Debugging verbracht, zum anderen hat YouTube angekündigt, den Support für den IE6 ab sofort auslaufen zu lassen. Das ist eine großartige Entscheidung, denn bisher hat sich kaum ein reichweitenstarkes Webangebot zu diesem Schritt durchringen können. Die Begründung halte ich für sehr stichhalting: YouTube sagt, dass sie der Support des IE6 glasklar messbar und nicht zu knapp Geld kostet und dass einige neue und praktische Funktionen mit vollem IE6-Support nicht machbar sind. Genau das ist der Punkt. Danke an Google für diesen mutigen Schritt. Denn nur durch Leidensdruck seiner Nutzer wird der IE6 aus den Statistiken verschwinden. Solange die Inhaltelieferanten die teilweise massiven Mehrausgaben bei der Entwicklung für den IE6 tätigen, wird sich an der Situation nichts ändern.

Ein viel gehörtes Argument ist ja, dass viele Nutzer an Firmen-PCs nur den Internet-Explorer 6 benutzen können/dürfen und so ja jetzt ausgeschlossen sind. Das stimmt. Na und? Eine reichweitenstarke Seite wie YouTube verliert dadurch vielleicht ein paar Prozent seiner Nutzer. Noch mal: Na und? YouTube ist wichtig genug, dass diese Leute im Zweifel schon einen Weg finden werden, sprich einen anderen Browser installieren. Oder sie lassen YouTube eben bleiben. Man darf nicht vergessen, dass da jemand mit einem Programm unterwegs ist, zu dessen Erscheinungszeitraum Videodienste wie YouTube noch unfassbare Zukunftsmusik waren. Woher kommt die Erwartungshaltung, dass das ohne Einschränkungen klappen muss? Ich denke, man muss sich einfach der Realität stellen. Es gibt genug Alternativen und keine davon kostet etwas.

Aber das CRM-System in unserer Firma (oder Intranet-Anwendung-XY) läuft nur mit dem Internet Explorer! Auch das höre ich immer wieder und ich habe zwei Antworten darauf: Erstens würde ich mich fragen, ob meine Intranet-Anwendung eine gute Anwendung ist, wenn sie die vorletzte Version eines so wichtigen Programmes als Zugangsvoraussetzung hat, aber da rede ich Firmen ungerne rein. Zum anderen aber spricht meiner Meinung nach nichts gegen den Paralleleinsatz von IE6 als Zugangsprogramm fürs veraltete Intranet und einem modernen Browser für das Internet. Selbst wenn es unbedingt der Internet Explorer 8 sein muss, gibt es Mittel und Wege, parallel einen IE6 zu betreiben. Zu viel Administrationsaufwand? Nun, so ist die Welt. Man denke im Firmeneinsatz übrigens auch an die haarsträubenden Sicherheitslücken des IE6, die nicht mehr behoben werden.

Aber was ist mit der Barrierefreiheit? Nutzer auszuschließen widerspricht dem Barrierefreiheitsgedanken, klar. Aber ist das hier wirklich so? Dafür muss ich eine Analogie bemühen: Man stelle sich vor, es gäbe ein Gesetz, das die Beschaffenheit von Rollstuhlrampen regelt. Alle Hersteller von Rollstühlen halten sich an diese Vorhaben und fahren prima damit. Nur der klare Marktführer hat bei früheren Modellen einmal diese Regeln anders ausgelegt und die Räder als Vielecke statt als Kreise ausgelegt. Das ist anfangs vielleicht Stand der Technik gewesen, technisch sinnvoll war es aber nie. Auf standardkonformen Rollstuhlrampen ist die Fahrt für Nutzer solcher Rollstühle dadurch etwas unbequem, weswegen alle Gebäudebetreiber ihre Rollstuhlrampen bisher sehr teuer in mechanisch sehr aufwändigen und vor allem technisch unsinnigen Varianten gebaut haben. Für die Nutzer standardkonformer Rollstühle gäbe es längst Entwicklungen, die die Nutzung von Rollstuhlrampen wesentlich bequemer und einfacher gestalten würden, aber diese sind mit den Vieleckrädern nicht oder nicht sinnvoll in Einklang zu bringen. Der Marktführer würde daher schon lange ein kostenloses Austauschprogramm für seine alten Modelle anbieten. Macht es hier Sinn, von einer Barriere zu sprechen, wenn man bei neuen Gebäuden die sich bietenden Vorteile nutzt und die Nutzer der veralteten Rollstühle zwingen würde, das kostenlose Austauschprogramm des Herstellers zu benutzen? Ich habe da meine Schwierigkeiten mit. Es geht ja nicht darum, dass der alte Rollstuhl die Rampe gar nicht mehr benutzen kann, es würde für etwas holpriger werden.

So sehe ich das auch beim IE6: Wer der Meinung ist, mit einem Browser aus dem Jahr 2001 im Jahr 2009 alle Funktionen moderner Websites genießen zu können, leidet unter massivem Realitätsverlust. Eine Website sieht komisch aus? Nun gut, da könnte man denken, der Seitenbetreiber wäre ein Idiot. Wenn aber immer mehr Websites komisch und kaputt aussehen und mir einhellig sagen, dass sie meinen veralteten Browser nicht mehr unterstützen, kann ich die alle doof finden oder mich der Realität stellen und ein Update machen. Genau deswegen braucht es Seiten wie YouTube, die die Eier haben, dieses doof gefunden werden einstecken zu können und im Zweifel ein paar Nutzer zu verlieren.

Hier kommt wieder der Geldaspekt ins Spiel. Mal angenommen, die Implementierung einer modernen Funktion ist im IE6 nicht möglich. Dann wird YouTube durchrechnen, was für einen finanziellen Wert die neue Funktion hätte. Dann wird YouTube gegenrechnen, was der Ausfall von einer angenommenen Zahl an IE6-Nutzern, die nicht umsteigen, sondern YouTube den Rücken kehren, kosten würde. Dann wird YouTube einrechnen, wieviel es wert ist, wenn x Prozent der ehemaligen IE6-Nutzer auf den Google-Browser Chrome umsteigt. Dann wird YouTube einen großen Strich unter die Rechnung machen und den IE6-Support sofort einstellen. Die Dimension, dass auch andere Google-Dienste vom Tod des IE6 profitieren, habe ich hier noch gar nicht einbezogen. Eine ähnliche Rechnung tut sich auf, wenn man die Entwicklungskosten für IE6-Zurechtbiegen gegen den Imageverlust durch etwas komisch aussehende Websites gegenrechnet.

Bei einem eigenen Projekt würde ich keinesfalls Geld in die Kompatibilität mit dem IE6 stecken und auf tolle neue Funktionen für alle anderen verzichten. Wer das Geld weiterhin ausgeben möchte, kann das ja weiterhin tun.

P.S. Ich muss dazu sagen, dass ich bei meinem letzten Auftrag einen Pauschalpreis veranschlagt und dabei u.a. die für das IE6/IE7 Debugging nötige Zeit völlig falsch eingeschätzt habe. Insgesamt habe ich nun mehrere Tage komplett unbezahlt (das entspricht meinen Fixkosten für einen ganzen Monat) da rein stecken müssen, was mich ernsthaft ärgert. Merke: Keine Pauschalpreise für so einen Mist und wenn doch, dann nicht so knapp kalkuliert.