Datums- und Zeitangaben zu formatieren ist immer wieder eine eher lästige Angelegenheit im Programmieralltag. Speziell, wenn später Anwender von verschiedenen Orten dieser Welt darauf zugreifen und damit einfach umgehen sollen. Schon die feinen Unterschiede in der Datumsschreibweise zwischen dem deutsch- und dem englischsprachigen Raum stiften oft genug Verwirrung.
Ein Beispiel: In allen drei Varianten ist der gleiche Tag gemeint – ohne die Landeszuordnung dahinter, ist eine eindeutige Zuordnung von Tag und Monat gar nicht so einfach.
- 6/15/2009 (en-US)
- 15/06/2009 (fr-FR)
- 2009/06/15 (ja-JP)
Um diesem Problem zu begegnen, unterstützen alle halbwegs modernen Browser (und damit auch der IE) die Methode Date.toLocaleString(), welche Datum & Zeit anhand der Browsereinstellungen im jeweils landestypischen Format ausgibt. Aus dem eher hässlichen Standard-GMT-String “Mon Jul 18 2011 11:56:29 GMT+0200” wird hierzulande “Montag, 18. Juli 2011 11:56:29”.
Weniger schön ist, dass im Chromium-Projekt seit langer Zeit ein ungefixter Bug (Issue 29779, eingetragen im Dezember 2009) schlummert, der statt “Monday, 18 January 2010 4:47:42 PM” eine solche Ausgabe provoziert “Mon Jan 18 2010 16:47:42 GMT+1100 (AUS Eastern Daylight Time) “. Nicht nur, dass keine Umformung in ein lokales Datumsformat stattfindet, durch die zusätzliche ausformulierte Zeitzonen-Angabe wird der String sogar noch länger und damit schwerer zu handhaben. Und da sich sowohl Google Chrome als auch Safari bei diesem Projekt bedienen, erben die beide Browser eben jenese Problem.
Ein Workaround – der eigentliche Aufhänger für diesen Blogpost – ist dabei gar nicht schwer. Denn das was Date.toLocaleString() ausgibt, ist lediglich eine Aneinanderreihung von lokalem Datum ( Date.toLocaleDateString() ) und lokalem Zeitformat ( Date.toLocaleTimeString() ) und für beides gibt es spezielle – und vor allem bugfreie – Methoden. Also einfach die beiden Einzelstrings miteinander verketten und fertig.
var date = new Date(); var localeString = date.toLocaleDateString()+" "+date.toLocaleTimeString();
Ich hoffe, dem einen oder anderen hilft dieser kleine Tipp.
Ostern ist gerade vorbei, doch ich habe noch eine kleine Überraschung. Seit der Veröffentlichung des YAML Builders 1.0 im Februar 2008 war mir klar, dass dies die Richtung ist, in die ich mit meinen zukünftigen Projekten verfolgen wollte. Zum einen bin ich selbst ein eher visuell orientierter Mensch, zum anderen wollte ich schon damals nicht akzeptieren, dass die Community zwar täglich Webapplikationen wie Google Mail & Docs sowie die Vorzüge von HTML5 hypt, der normale Webentwickler aber seine CSS-Layouts in der Regel auch heute noch im Texteditor schreibt und immer wieder den Browser anklickt, F5 drückt, um sein Getipptes alle paar Minuten auf Fehlerfreiheit zu überprüfen. Das kann nicht die Zukunft sein.
Also habe ich angefangen, darüber nachzudenken, wie sich das Konzept hinter dem YAML-Builder sinnvoll aufbohren lässt. Nach zahlreichen Diskussionen, Tests und JavaScript-Lernerei habe ich angefangen. Dieser Beginn meines neuen Projektes »Thinkin’ Tags« liegt nun ca. 2 Jahre zurück und es ist Zeit, die ersten Ergebnisse der Programmierarbeit der letzten zwei Jahre vorzustellen.
Das Projekt »Thinkin’ Tags«
»Thinkin’ Tags« ist eine völlig neuartige, browserbasierte Entwicklungsumgebung für das schnelle Erstellen von Layout-/Webseiten-Prototypen mit bisher einzigartigen Features. »Thinkin’ Tags« ist als webbasierter Dienst konzipiert, der nach erfolgreicher Betaphase neben einem kostenfreien Zugang auch kostenpflichtige Premiumfeatures anbieten wird (allerdings wird bis dahin noch etwas Zeit vergehen). Die Layout-Prototypen können entweder von Grund auf mit einfachem HTML & CSS erstellt werden oder optional auf Basis verschiedener CSS-Frameworks. Dabei steht selbstverständlich YAML (aktuell in der Version 4 alpha3) zur Verfügung aber auch Grid-Frameworks wie Blueprint CSS (bereits experimentell implementiert) sowie zukünftig auch 960.gs sind angedacht.
Der große Vorteil des browserbasierten Prototypings in Verbindung mit einem CSS-Framework ist, dass der auf diese Weise entstehende Code in großen Teilen weiter- bzw. wiederverwendbar ist für die finale Umsetzung des Layouts für den Produktivbetrieb. Einerseits erlaubt der visuelle Ansatz, CSS-Layouts im Browser zu »entwerfen«, denn dank der mittlerweile hervorragenden Performance aktueller Browser und den visuellen Gestaltungsmöglichkeiten mit CSS2 und CSS3 ist das Vorzeichnen in Grafikprogrammen wie Photoshop in vielen Fällen unnötig. Andererseits sichert die professionelle Codebasis und die Ausrichtung von »Thinkin’ Tags« als Werkzeug für erfahrene Frontendentwickler eine Codequalität, die ein eine annähernd vollständige Übernahme des Prototypen in die nachfolgenden Enwicklungsschritte ermöglicht. Und auch wenn in der Vergangenheit zahlreiche desktopbasierte WYSIWYG-Editoren (Dreamweaver, GoLive, ExpressionWeb) nicht das erreicht haben, was ihre Werbung verspricht, ist dieser Ansatz innerhalb eines Browsers ausgesprochen reizvoll.
Das folgende Video basiert auf einem etwas älteren Entwicklungsstand (Januar 2011), es gibt jedoch einen recht guten Überblick darüber, wie die Applikation bedient wird und was in technischer Hinsicht momentan möglich ist.
Einige Features ...
- Vollständig browserbasierte Erstellung von Layout-Prototypen (in Firefox, Chrome, Safari und Opera)
- Unterstützung für CSS-Frameworks YAML und Blueprint CSS (960.gs in Vorbereitung)
- Der Anwender hat nahezu vollständige Kontrolle über Markup und CSS
- CSS-Parser zeigt CSS-Eigenschaften einschließlich Vererbung an
- Jegliche CSS-Änderungen werden unmittelbar sichtbar
- Verschiedene Darstellungsmodi zur Erstellung des Markups, sowie des Screen- und Print-Layouts
- Projektexport und Download als ZIP-File
Die ersten Hinweise auf den Entwicklungszweig für YAML 4.0 habe ich ja bereits im Oktober letzten Jahres gegeben. In dem damaligen Beitrag habe ich allerdings noch nicht wirklich Informationen zur Version 4 gegeben sondern eher über die Dinge berichtet, die aus dem 4.0er Zweig in die Version 3.3 vorgezogen wurden. Heute hingegen werde ich ein bisschen aus dem Nähkästchen plaudern, wo die Reise bei YAML 4 hingehen wird. Und damit gehts auch gleich los ...
Namespaces
[Status: 85% fertig] Eines der häufigsten Quellen für Probleme bei der Frontendentwicklung in Verbindung mit Content Management Systemen, speziell bei größeren oder über Jahre gewachsenen Projekten, sind Kollisionen von ID- und Klassennamen. Beileibe nicht jedes CMS gestattet die vollständige Kontrolle über das ausgelieferte Markup. Wordpress weist beispielsweise dem <body> Element dynamisch eine Vielzahl von CSS-Klassennamen zu, was sich für Normalanwender auch kaum unterdrücken lässt. JavaScript Widgets wie Slider, Galerien etc. benötigen für den Zugriff auf ihr Markup sinnvolle IDs und Klassennamen – gleiches gilt für CSS Frameworks.
Für den Entwickler ist es gleichermaßen wichtig, möglichst selbsterklärende und konsistente Bezeichnungenzu verwenden, um die langfristige Wartbarkeit des Codes zu sicherzustellen. Eingänglich klingende, kurze Bezeichnungen wie “wrapper”, “post”, “page” usw. haben daher großes Konfliktpotential. Auf YAML bezogen kollidiert beispielsweise die von YAML verwendete CSS-Klasse .page mit der Verwendung, die Wordpress für die CSS-Klasse “page” vorsieht, die es dem <body> Element standardmäßig zuweist. Die Lösung hierfür heisst: Namespaces.
In YAML 4 werden daher die CSS-Klassen und IDs der Kernbestandteile des Frameworks mit einem Präfix versehen werden. Ein einheitlicher Namespace hat zudem den Vorteil, dass er (wir reden schließlich bei HTML/CSS von einfachen ASCII-Dateien) bei Bedarf leicht angepasst werden kann.
Ich bin ganz sicher nicht der klassische Programmierertyp und so lerne ich Programmiersprachen – im konkreten Fall JavaScript –, in dem ich mich herausfordernden Projekten stelle, um dabei Neues zu lernen. Leider ist dieses “Neue” nicht immer ganz logisch und führt schonmal dazu, dass sich Stirn und Tischplatte unaufhaltsam anzuziehen scheinen. So auch das Thema Pointer in JavaScript, welches mir gestern Abend aufgestoßen ist.
Wenn man ein wenig Erfahrung aus anderen Programmiersprachen wie C mitbringt, dann ist einem der Unterschied zwischen einem Objekt und dem Pointer auf ein Objekt bekannt. Das entscheidende dabei: Bei C kann man sehr einfach festlegen, ob man einer Variable eine Objektkopie zuweist oder nur einen Pointer auf das Originalobjekt erzeugt. Bei JavaScript sieht das etwas anders aus.
Obgleich in JavaScript so ziemlich alles als Objekt betrachtet werden kann, so gibt es doch feine aber entscheidene Unterschiede, wie diese intern behandelt werden. Folgender Code machte mich stutzig:
var layoutCSS = {
'width': 'auto',
'min-width': '720px',
'max-width': '80em'
};
var minSettings = layoutCSS;
minSettings['max-width'] = 'none';
console.log(minSettings); //"none"
console.log(layoutCSS); //"none"
Wie man sieht, wird in diesem Beispiel nicht etwa eine Kopie des Objekts layoutCSS in minSettings angelegt, sondern lediglich ein Pointer auf das Originalobjekt. In der Konsequenz ändert sich der Inhalt des OriginalObjekts layoutCSS bei Zuweisungen an minWidth. Gut zu wissen, denn in JavaScript ist dieses Verhalten auf Arrays und Objekte begrenzt. Strings hingegen werden kopiert, obwohl sie intern ebenfalls wie Objekte behandelt werden. Aufklärung darüber, wie JavaScript mit Pointern umgeht, liefert der Artikel Understanding Pointers in JavaScript.
Soweit so nervig gewöhnungsbedürftig. Wie aber kommt man jetzt zu seiner Kopie bzw. Clone eines Arrays oder eines Objekts? Leider ist es auch hier so – ähnlich wie beim Versuch, ein assoziatives Array zu sortieren – dass JavaScript den Programmierer bei dieser Frage weitgehend im Stich läst. Handarbeit ist demnach angesagt. Einen ersten Lösungsansatz liefert der Artikel von Brian Huisman "How to copy arrays and objects in Javascript", der eine .clone() Methode einführt:
Object.prototype.clone = function() {
var newObj = (this instanceof Array) ? [] : {};
for (item in this) {
if (item == 'clone') continue;
if (this[item] && typeof this[item] == "object") {
newObj[item] = this[item].clone();
} else newObj[item] = this[item]
} return newObj;
};
Speziell für jQuery-Nutzer gibts von John Resig höchstpersönlich noch einen kürzeren Vorschlag über die jQuery.extend():
// Shallow copy
var newObject = jQuery.extend({}, oldObject);
// Deep copy
var newObject = jQuery.extend(true, {}, oldObject);
Zwar finde ich persönlich diese Inkonsistenz bei JavaScript etwas nervig, dass man selbst nicht über Kopie oder Pointer wählen kann, aber was soll's. Wenigstens gibt es halbwegs einfache Lösungswege aus diesem Dilemma. An dieser Stelle ein ganz dickes Dankeschön an das kalifornische JavaScript-Lexikon Dirk Ginader, der mir mit diesen Links den Abend gerettet hat.
Seit einiger Zeit ist es in Bloggerland Tradition, den liebgewonnenen, schokoladengetriebenen Türchen-Wahn der Vorweihnachtszeit in leicht abgewandelter Form (Pralinen zu Blogbeiträgen) auch im Internetz aufleben zu lassen. Und so finden sich jedes Jahr an verschiedenen Stellen Autoren zusammen, um ihren Lesern mit 24 Blogposts den einen oder anderen Tipp für die tägliche Arbeit mit auf den Weg zu geben. Und da es jedes Jahr mehr werden, hier eine kleine - sicherlich unvollständige - Liste:
- Webkrauts Adventdskalender 2010
- Der Adventskalender der Webkrauts erscheint bereits seit 2005 und widmet sich in jedem Jahr einem übergeordneten Thema. In diesem Jahr sind dies die “Kunden”
- 24ways 2010
- Was der Webkrauts-Kalender im deutschsprachigen Raum ist, ist 24ways auf der großen internationalen Bühne. Das who-is-who der Szene trifft sich zu 24 abwechslungsreichen Beiträgen rund um das Thema modernes Webdesign
- WPEngeneers - Advent Calendar
- Meines Wissen zum zweiten Mal starten die Programmierprofis ihren Adventskalender rund um das Thema “Wordpress”
- Maddesigns CSS3-Adventskalender
- Sven Wolfersmann ist ein ganz harter Bursche und zieht dieses Jahr einen Adventskalender zum Thema CSS3 fast alleine durch. Ich bin gespannt ...
- HTML5-Demos-Adventskalender
- Wie es der Name schon sagt ... it’s all about HTML5
Na denn, für Lesestoff ist gesorgt ...
Neueste Kommentare
- Tenzin | 01.02.12 (12:22 Uhr)
YAML 4 Release - Generationswechsel eingeläutet…
- Hans | 26.01.12 (18:24 Uhr)
YAML 4 Release - Generationswechsel eingeläutet…
- Dirk | 25.01.12 (19:22 Uhr)
YAML 4 Release - Generationswechsel eingeläutet…
- Hans | 25.01.12 (18:44 Uhr)
YAML 4 Release - Generationswechsel eingeläutet…
- Stefan | 21.01.12 (03:03 Uhr)
YAML 4 Release - Generationswechsel eingeläutet…
- Benni | 20.01.12 (15:02 Uhr)
YAML 4 Release - Generationswechsel eingeläutet…
