Zen Coding HTML

Jeder der sich ein wenig mit CSS und Javascript, und dort vor allem mit Javascript-Frameworks beschäftigt hat, wird früher oder später schonmal über eine Selektor-Engine gestolpert sein.


So setzt eigentlich jedes dieser Frameworks auf eine Engine zum Holen und Weiterverarbeiten von DOM-Elementen. Für jQuery wäre hier zum Beispiel die im 1.3er-Release als eigenständiges Projekt ausgegliederte Engine Sizzle zu nennen.
Im Kern ermöglichen diese Frameworks dem Entwickler die aus CSS bekannten Selektoren für den Element-Zugriff zu nutzen; und das auch Cross Browser-kompatibel (IE6+, FF2+, Opera, Safari, etc) mit den wesentlich mächtigeren, aber leider von Browsern noch selten voll unterstützten CSS3-Selektoren.

Was passiert nun, wenn dieses Konzept des Ansprechens von DOM-/HTML-Elementen auf den Kopf gestellt wird, und nicht mehr Element-Selektion das Ziel eines Selektors ist, sondern Element-Erzeugung; dieser Selektor die durch ihn selektierten Elemente also erst erzeugt?

Diese Idee zu Ende gedacht hat Sergey Chikuyonok , nachdem zuvor im April 2009 Vadim Makeev diese in einem Artikel erstmals vorschlug. Er entwickelte eine Library für viele etablierte Text-Editoren, genannt Zen Coding , und taufte die Selektoren in diesem Kontext zu "Abbreviations" um.

Einstieg

Als einfacher Einstieg soll folgendes Beispiel dienen:

Abbreviation:

div#content>h1+p

Als normaler CSS-Selektor gelesen würden durch diesen Ausdruck alle <p>-Tags selektiert, die sich direkt hinter einem <h1>-Tag befinden, welches selber direktes Kind des <div>-Tags mit der id "content" ist.
Wendet man nun auf diese Abbreviation die in Zen Coding definierte Funktion "expand" an, so wird folgender HTML-Code erzeugt:

<div id="content">
  <h1></h1>
  <p></p>
</div>

Der Ausdruck wird also von links gelesen ausgewertet, und beim Verfolgen der einzelnen Teile des Ausdrucks werden diese erzeugt. Also zuerst ein <div>-Tag mit der id "content", darin als direktes Kind ein <h1>-Tag mit benachbartem <p>-Tag.

"Expand Abbreviation"

Dieser Hauptbestandteil von Zen Coding nennt sich "Expand Abbreviation".
Er unterstützt neben:

  • dem einfachen Erzeugen von Tags (div, p)
  • dem Hinzufügen von ids (div#content),
  • und classes (p.error.critical)
  • dem Erzeugen von Tags mit Kind-Elementen (div>p, div>p>span)
  • dem Erzeugen benachbarter Tags (h1+p, div#header+div#content+div#footer)
  • und dem Erzeugen multipler Elemente (ul>li*5, ul>li*5>a)

auch die Nummerierung der Elemente innerhalb von ids und classes (ul#nav>li.item-$*5).
All diese Operatoren sind beliebig kombinier- und schachtelbar, und geben dem Webentwickler ein komplettes Toolset zum Erzeugen aller vorstellbaren HTML-Code-Fragmente.

Beispiele

Ein paar weitere Beispiele zur Verdeutlichung:

Abbreviation:

div#header>img.logo+ul#nav>li*4>a

Ausgabe:

<div id="header">
  <img src="" alt="" class="logo" />
  <ul id="nav">
    <li><a href=""></a></li>
    <li><a href=""></a></li>
    <li><a href=""></a></li>
    <li><a href=""></a></li>
  </ul>
</div>

Abbreviation:

div#content>h1.caption+p.abstract+p

Ausgabe:

<div id="content">
  <h1 class="caption"></h1>
  <p class="abstract"></p>
  <p></p>
</div>

Je nach Editor wird nach der Generation des Codes zusätzlich der Cursor in das erste zu befüllende Feld (im letzten Beispiel zum Beispiel der Inhalt des <h1>-Tags) gesetzt, und mit jedem Tab kann im generierten Snippet sequenziell durch alle weiteren Felder gesprungen werden (z.B. href, src, alt, etc).

Snippets / Erweiterbarkeit

Die per Default eingefügten Attribute lassen sich in den mitgelieferten Snippets ändern und ergänzen. Es können auch gänzlich neue Snippets hinzugefügt werden, um eigene Code-Fragmente zur Verfügung zu haben. Angereichert zum Beispiel durch if-Abfragen für Rails-Views sieht das dann wie folgt aus:

Code-Snippet "rails_if":

<% if @{id} -%>\n\t${child}\n<% endif -%>

Abbreviation:

rails_if#logged_in>div#status>p.logged_in

Ausgabe:

<% if @logged_in -%>
  <div id="status">
    <p class="logged_in"></p>
  </div>
<% endif -%>

"HTML Pair Matcher" und "Wrapping with Abbreviation"

Weitere, leider nicht in allen Editoren unterstützte Features sind der "HTML Pair Matcher" zum Selektieren der um den Cursor liegenden Elemente (die Selektion kann dabei schrittweise nach Aussen vergrößert oder nach Innen verkleinert werden) sowie das "Wrapping with Abbreviation" das um in über mehrere Zeilen liegende Strings Code mittels einer Abbreviation legt.
Der Stern dient dabei als Referenz welcher Code um jeden String erzeugt wird, während der Teil der Abbreviation vor dem Stern den Code um alle Strings bestimmt:

Abbreviation:

div#header>ul#navigation>li.item$*>a>span

angewendet auf:

Leistungen
  Produkte
  Unternehmen
  Kunden
  Mitarbeiter
  Veranstaltungen
  Blog

Ausgabe:

<div id="header">
  <ul id="navigation">
    <li class="item1"><a href=""><span>Leistungen</span></a></li>
    <li class="item2"><a href=""><span>Produkte</span></a></li>
    <li class="item3"><a href=""><span>Unternehmen</span></a></li>
    <li class="item4"><a href=""><span>Kunden</span></a></li>
    <li class="item5"><a href=""><span>Mitarbeiter</span></a></li>
    <li class="item5"><a href=""><span>Veranstaltungen</span></a></li>
    <li class="item5"><a href=""><span>Blog</span></a></li>
  </ul>
</div>

Unterstützte (Text-)Editoren

Unterstützt werden bisher folgende Editoren voll:

und folgende Editoren teilweise (nur "Expand Abbreviation"):

Diese Liste wird aber fast im Tages-Takt durch neue Editoren ergänzt und vergrößert, so das sich ein regelmäßiger Blick auf die Projektseite von Zen Coding auch für Nutzer anderer Text-Editoren lohnt.

Download und Weiterführendes

Zu finden sind Dokumentation und Plugins unter:
http://code.google.com/p/zen-coding/

Ausserdem dort zu finden sind die HTML- und CSS-Pakete zur verbesserten Code-Completion für ausgewählte Editoren.

Den Blogpost von Sergey Chikuyonok zum Release von Zen Coding findet man hier:
http://www.smashingmagazine.com/2009/11/21/zen-coding-a-new-way-to-write-html-code/

Zuletzt noch das Video von Sergey Chikuyonok, in dem er die Features in Form eines kurzen Screencast vorstellt:
http://vimeo.com/moogaloop.swf?clip_id=7405114.


Zur Blog-Übersicht