Das <wbr>-Element in HTML5

Veröffentlicht am 9. August 2010

Das <wbr>-Element ist, soweit ich feststellen konnte, eine Erfindung aus Netscape 4. Was es in HTML5 zu suchen hat weiß ich nicht (es ist nicht nur archaisch, sondern auch recht nutzfrei), aber der Chronistenpflicht wegen habe ich es letzte Woche mal erforscht. Das <wbr>-Element repräsentiert eine Möglichkeit zum Zeilenumbruch, d.h. da wo es steht, kann der Browser einen Zeilenumbruch einfügen, wenn er das brauchen sollte.

Beispiel:

<h1>Mit <code>&lt;wbr&gt;</code></h1>
<p style="width:100px; border:1px solid red;">
    Donau<wbr>dampf<wbr>schiff<wbr>fahrts<wbr>gesellschaft
</p>

<h1>Ohne <code>&lt;wbr&gt;</code></h1>
<p style="width:100px; border:1px solid red;">
    Donaudampfschifffahrtsgesellschaft
</p>

Ergebnis:

Das WBR-Element in HTML5

Der Browsersupport ist recht medium, in Opera und Internet Explorer 8 funktioniert <wbr> nicht, wohl aber in allen anderen Browsern inklusive IE7 und IE6. In Opera lässt sich das Problem relativ einfach fixen, indem man per CSS hinter jedem <wbr> ein Zero-Width-Space einfügt:

wbr:after {
    content: "\00200B"
}

Dieses Leerzeichen ist unsichtbar, trennt aber das Wort auf und ermöglicht so einen Zeilenumbruch wie ein normales Leerzeichen. Im IE8 kann man das gleiche mit JavaScript erreichen:

var wbrs = document.getElementsByTagName('wbr');
var num_wbrs = wbrs.length;
if(num_wbrs > 0 && HTMLTextElement && wbrs[0] instanceof HTMLTextElement){
    for(var i = 0; i < num_wbrs; i++){
        wbrs[i].insertAdjacentHTML('afterEnd', '&#x200b;');
    }
}

Hier ist vielleicht noch bemerkenswert, dass die im JS-Code verwendete insertAdjacentHTML()-Methode seit HTML5 auch erstmals Standard ist, was natürlich nicht heißt, dass sie in einer nennenswerten Anzahl Browser funktioniert.

Das <wbr>-Element ist recht nutzlos, da es zwar Wörter trennt, aber keine Trennstriche einfügt. Das Entity &shy; macht genau das und ist daher vermutlich in vielen Fällen die bessere Wahl:

<h1>Wbr</h1>
<p style="width:100px">
    Donau<wbr>dampf<wbr>schiff<wbr>fahrts<wbr>gesellschaft
</p>

<h1>Shy</h1>
<p style="width:100px">
    Donau&shy;dampf&shy;schiff&shy;fahrts&shy;gesellschaft
</p>

Ergebnis:

Das Shy-Entity und WBR im Vergleich

Allerdings weiß ich aus dem Stand gerade nicht, wie aktuell die Browserunterstützung für &shy; aussieht – was ich aber mal vor Jahren ausprobiert habe, war die Suchmaschinenfrundlichkeit. Hier gibt es keine großen Probleme zu berichten, bis auf die Produkte aus dem Hause Microsoft ignorieren alle Suchmaschinen &shy; und finden auch Keywords, die im HTML entsprechend getrennt sind.

Fazit: auf jeden Fall für mögliche Zeilenumbrüche &shy; verwenden und sich angesichts von <wbr> einfach nur fragen, was die HTML5-Jungs und -Mädels in ihren Pausen eigentlich so rauchen.

MODx Revolution: mehrere Websites aus einer einzigen Installation heraus betreiben

Veröffentlicht am 5. August 2010

Ich werkele regelmäßig für eine Agentur, deren Kunde ganze Breitseiten an Öffentlichkeitsarbeit in die Welt hinauspumpt. Dafür reicht natürlich eine einzige Website nicht, sondern da wollen gleich ganze Netzwerke befüllt werden. Da aber jeweils die gleichen Redakteure an den Seiten arbeiten, wäre es natürlich schön und effizient, wenn die Verwaltung dieses ganzen Netzwerks über ein gemeinsames Interface möglich wäre. Mit MODx Revolution ist die Umsetzung von so etwas zum Glück geradezu trivial.

Schritt 1: Kontext anlegen

MODx Revolution bietet die Möglichkeit, Sets von Systemeinstellungen anzulegen, die die eigentlichen Systemeinstellungen punktuell überschreiben. Das ist für uns wichtig, weil die verschiedenen Websites unterschiedliche Titel haben sollen und unter unterschiedlichen Domains laufen, sich also in einigen wenigen Dingen von der Grundkonfiguration unterscheiden. Ein solches Set von abweichenden Systemeinstellungen heißt in MODx „Kontext“ und kann unter System → Kontexte angelegt werden. Die zu dort einzutragenden Einstellungen sind für eine eigene Seite in der Regel mindestens die folgenden:

  • site_start und base_url: Startseite und Basis-Adresse
  • site_name: Titel der Seite
  • http_host und base_url: Host und Pfad der jeweiligen Seite

Dazu ist es ratsam, auch für angepasste Fehlerseiten u.Ä. zu sorgen, wobei die Keys dieser Einstellungen einfach aus den Systemsettings ermittelt werden können. Und das ist auch schon alles, was man im MODx-Manager selbst einrichten muss. Der neue Kontext sollte im links im Ressourcenbaum erscheinen und kann bereits mit Seiten befüllt werden.

Schritt 2: Dateien und Domains

Nun ist noch dafür zu sorgen, dass der neu angelegte Kontext beim Aufruf über die neue Domain auch verwendet wird. Das wird mit einem ganz simplen Hack gemacht: einfach die Dateien config.core.php, index.php und .htaccess aus dem Modx-Hauptverzeichnis in ein eigenes Unterverzeichnis kopieren und die Domain oder Subdomain der neuen Seite auf dieses Verzeichnis zeigen lassen. Dann die index.php öffnen und gegen Ende der Datei eine Zeile finden, die so oder ähnlich aussieht:

$modx->initialize('web');

Das, was hier als Parameter an initialize() übergeben wird, ist der Name des zu verwendenden Kontexts – standardmäßig web. Das tauschen wir einfach gegen den Namen unseres neuen Kontexts aus … und das war es dann auch schon! Nochmal zusammengefasst:

  1. Ein Set von abweichenden Systemeinstellungen für die neue Seite anlegen
  2. Drei Dateien kopieren und eine Zeile anpassen, damit die neuen Einstellungen verwendet werden

Ruft man jetzt die Domain der neuen Seite auf (die in das neue Verzeichnis mit den kopierten Dateien zeigt), wird der gewünschte Kontext initalisiert – mit all seinen Einstellungen, Ressourcen und Rechten für Redakteure.

Fertig!

Natürlich braucht es im Detail noch hier und da ein paar Feinjustierungen, aber prinzipiell sind diese beiden Schritte alles, was man machen muss, um mehrere Websites mit einer einzigen MODx-Installation zu betreiben. Nutzen kann das man dies nicht nur für größere Netzwerke, sondern zum Beispiel auch für verschiedene Sprachversionen einer Seite. Mit dem Rechtesystem ist es auch möglich, bestimmte Redakteure nur bestimmte Kontext-Bereiche mit Seiten befüllen zu lassen.

Im übrigen: das gesamte Backend von MODx Revolution ist mit genau dieser Technik umgesetzt – wer es nicht glaubt, kann ja mal den Kontext-Key mgr unter die Lupe nehmen und nachsehen, welche drei Dateien denn da im Manager-Verzeichnis liegen.

Probleme, Lösungen und Tipps

Ein etwas ekliger Aspekt solcher Seiten ist das Kampf mit den URLs verlinkter Ressourcen (Bilder, PDFs etc) in Kombination mit einem WYSIWYG-Editor. Ich nehme zwar an, dass man das alles innerhalb von MODx konfigurieren kann, aber was auch nicht verkehrt ist, ist der Weg über Symlinks oder mod_rewrite – einfach für alle Domains eigene Ressourcenverzeichnisse simulieren, die nichts als Verweise oder Redirects auf einen großen gemeinsames Ressourcenpool sind. Lieber zwei Zeilen in die .htaccess schreiben als groß in der Konfiguration herumfummeln!

Als weiteres praktisch-billiges Tool hat sich dieses Gib-Text-anhängig-vom-aktiven-Kontext-aus-Snippet erwiesen:

$contextkey = $modx->resource->_contextKey;
$contexts = array('foo-de', 'foo-en', 'bar-de', 'bar-en');
foreach($contexts as $context){
    if($context == $contextkey && !empty(${$context})){
        return ${$context};
    }
}

Damit kann man in Templates und Chunks flexibel Textbrocken ja nach aktiver Seite und/oder Sprache ausgeben, einfach indem man z.B. aufruft. Dererlei geht zwar auch über Lexicon-System von MODx, aber wenn es auch mal schnell und dreckig sein darf, reicht dieses Snippet.

Zum Abschluss noch drei allgemeine Tipps aus nun schon mehrmonatiger Erfahrung mit solchen Konstruktionen:

  1. Bei der Auswahl der Kontext-Keys bietet es sich an, sie so zu benennen, dass man die Namen in Snippets parsen kann und automatisch festellen lassen kann, zu beispielsweise welcher Seite oder Sprache ein Kontext gehört. Ich mag das Muster seite-sprache, also z.B. foo-de, foo-en, foo-pl, bar-de, bar-en und so weiter
  2. Baut kontext- und sprachagnostische Snippets. Der Aufwand für Ressourcen-Recycling innerhalb einer MODx-Installation liegt bei 0 – wenn man entsprechend geplant hat. Nicht vergessen dass es ja in Revo auch Platzhalter in Chunks gibt!
  3. Nutzt um Himmels Willen Kategorien um Ressourcen zu sortieren! Wenn man mehr als eine Seite in mehreren Sprachen betreiben sollte, ist das die einzige Chance den Durchblick zu bewahren.

Fragen zu HTML5 beantwortet

Veröffentlicht am 2. August 2010

Wenn ich Fragen zu HTML5 via E-Mail oder Twitter erreichen, ist es manchmal schade, dass einige sehr gute Fragen (nebst Antworten) der Allgemeinheit entgehen. Deshalb eröffne ich hier eine kleine Sammlung mit interessanten Fragen und meinen Antworten der letzten paar Wochen zum Buch und zu HTML5. Wenn es sich lohnt wird das eine kleine Artikelserie. Wer mehr Fragen hat: Nur raus damit, egal ob in die Kommentare oder per Mail oder anderweitig!

Warum HTML5?

Ich erkenne nicht so ganz den Vorteil von HTML5, abgesehen vielleicht von Video- und Canvas-Element. Warum sollte ich zu HTML5 migrieren?

Wenn dir HTML5 etwas überflüssig vorkommt, liegt das vermutlich daran, dass du an Websites denkst. Für Websites ist HTML5 aber nicht vorrangig gemacht, sondern für Webapplikationen. Für den neuen Firmenauftritt der Beispielmüller GmbH wird man vermutlich kein HTML5 brauchen (auch wenn es nicht schaden wird), wohl aber für Webapps, die Desktop-Anwendungen Konkurrenz machen sollen. HTML5 hieß nicht umsonst ursprünglich „Web Applications 1.0“. Für den Einsatz von HTML5 für Websites spricht neben den neuen semantischen Elementen und den neuen Features für Formulare vielleicht noch, dass die Syntax ein klein wenig einheitlicher und einfacher ist und Möglichkeiten zur Verkürzung bietet (sofern man denn auf so etwas steht). Man muss aber nicht migrieren – wenn man mit XHTML 1 oder HTML 4 alles machen kann was man möchte, kann man ruhigen Gewissens beim Altbewährten bleiben. Ich empfehle an dieser Stelle einfach mal einen Blick auf drei Dinge, für die man bereits jetzt mit HTML5 (im jedem Browser) anstellen kann.

Wann kommt das E-Book?

Wird es dein Buch auch als PDF oder ePub fürs iPad geben? Ständig eine Bibliothek in Papierform rumschleppen ist sehr lästig.

Ja, eine E-Book-Ausgabe (sowohl PDF als auch ePub) ist geplant und soll laut Verlag "in Kürze" (wann immer das auch genau sein mag) verfügbar sein. Ich werde es ankündigen wenn es soweit ist.

Welches Element für Fat Footers?

Sollte man sog. „Fat Footers“ (also Footer mit viel Inhalt, Linklisten o.Ä.) auch in eine <aside> packen? Oder in einen <footer>? Eine Blog-Sidebar und ein Fat Footer unterscheiden sich ja inhaltlich kaum.

Ein Footer gehört prinzipiell in ein <footer>-Element, denn genau dafür ist das Element da. Es ist laut Spezifikationen auch explizit für typische Fat-Footer-Inhalte freigegeben (...typically contains information about its section such as who wrote it, links to related documents, copyright data, and the like). Dabei ist das <aside>-Element durchaus ähnlich, allerdings muss man beachten, dass es Sectioning Content ist, sich also auf die Outline auswirkt. Möchte man, dass ein Footer ein eigener Seitenbereich ist? Wahrscheinlich in den meisten Fällen nicht.

Wie rotiere ich Elemente auf einer Canvas?

Wie kann ich in einem canvas mit mehreren Elementen ein einzelnes Element rotieren ohne dass die anderen mitrotieren? Bei meinen Versuchen mit context.rotate() rotiert immer der gesamte Inhalt. Habe schon daran gedacht alle Elemente auf einzelne canvas zu zeichnen und diese per z-index übereinanderzulegen aber ich hoffe, Sie können mir einen einfacheren Weg zeigen.

Die Sache ist ganz einfach: es gibt keine „Elemente“ auf einer Canvas. Eine Canvas ist nur eine Malfläche mit Pixeln und rotiert wird immer nur das unsichtbare Koordinatensystem, an dem die Pixel gezeichnet werden. Mein Vorschlag für das Problem:

  1. context.save()
  2. context.rotate()
  3. „rotiertes“ Element zeichnen
  4. context.restore()
  5. alle anderen Elemente zeichnen

So kommt nur das zu rotierende Element in den Genuss eines gedrehten Koordinatensystems, während alle anderen nach dem Aufruf von context.restore() wieder anhand eines normalen Koordinatensystems gezeichnet werden.

Weitere Fragen?

Eure Fragen zu HTML5 beantworte ich gerne! Einfach eine E-Mail schreiben oder Formspring bemühen und ein bisschen Geduld haben – falls ich gerade unterwegs bin, kann es mit Antwort manchmal etwas dauern, doch früher oder später schreibe ich garantiert zurück.

Hardware-Review: Logitech Wireless Presenter R400

Veröffentlicht am 30. Juli 2010

Logitech Wireless Presenter R400

Wer mir auf Twitter folgt, dem ist sicher nicht entgangen, dass ich diese Woche in München eine HTML5-Schulung gehalten habe. In Vorbereitung hierauf habe ich so manches gelesen und gekauft, unter anderem den Wireless Presenter R400 von Logitech. Dabei handelt es sich um eine Fernbedienung für Präsentationen mit eingebautem Laserpointer. Mein Fazit nach drei Tagen intensiver Dauer-Benutzung: Wer regelmäßig Slides an Leinwände wirft und dabei nicht vor seinem Computer festgenagelt sein will, muss so ein Teil haben.

Der 11cm lange Wireless Presenter R400 hat neben der Taste für den Laserpointer und einem kleinen An/Aus-Schalter an der Seite vier Tasten zur Steuerung von Präsentationen – Slide vor, Slide zurück, Abdunkeln und eine weitere Taste zum Starten der Präsentation. Hinzu kommt eine einfache Batterieanzeige. Der Anschluss an den Computer erfolgt über ein kleines USB-Modul, das im Presenter selbst verstaut wird und das keinerlei Installation bedarf. Mitgeliefert werden eine Bedienungsanleitung, zwei Batterien und eine schicke kleine Kunststofftasche mit Reißverschluss.

Die beigelegte Bedienungsanleitung ist freilich komplett überflüssig, da sich die Tasten selbst erklären und eine Installation wie gesagt nicht nötig ist. Die Reichweite von 15 Metern ist beachtlich und das Gerät liegt perfekt und rutschfest in der Hand, so dass man kreuz und quer durch den Raum toben und trotzdem immer seine Präsentation steuern kann. Sowohl unter Windows wie auch OS X und Linux funktioniert der Presenter ohne Mucken und erledigt zuverlässig seinen Job.

Logitech Wireless Presenter R400 (Detailansicht)

Mein einziger, winziger Kritikpunkt betrifft die Anordnung der Taste zum Abdunkeln, denn diese befindet sich genau unter der Taste für „Slide vor“. Ein Verwechseln der Tasten ist zwar aufgrund ihrer Formgebung ausgeschlossen (die Abdunkeln-Taste ist wesentlich kleiner und die „Slide vor“-Taste hat einen kleine Erhebung) und da die Tasten Vertiefungen haben, wird weitgehend verhindert, dass man abrutscht. Genau das ist mit aber im Eifer des Gefechts zwei mal passiert, was durchaus einer gewissen wurstfingerigkeit meiner Person anzulasten ist. Das Problem ist, dass bei diesem Abrutschen nach unten man dummerweise genau auf die Taste gerät, die durch ein Abdunkeln einen halben Totalschaden hervorruft. Vielleicht wäre es besser gewesen, an dieser Stelle die „Präsentation starten“ zu platzieren und diese so auszulegen, dass sie bei laufenden Präsentationen einfach nichts tut – so wäre ein versehentliches Abwürgen der Präsentation komplett ausgeschlossen.

Unterm Strich ist festzuhalten, dass wie gesagt der Logitech Wireless Presenter R400 ein Muss ist, wenn man öfter Slides an die Wand zu werfen gedenkt. Wer dererlei auch unter Zeitdruck machen muss, sollte vielleicht auch einen Blick auf die etwas kostenintensivere Deluxe-Variante R800 riskieren – hier ist neben verdoppelter Reichweite (wobei, wer braucht 30 Meter?) auch ein Display mit Timer geboten.