Justin Palmer hat ein Snippet für Prototype gepostet welches das Date Object um strftime() erweitert.
-
Object.extend(Date.prototype, {
-
strftime: function(format) {
-
var day = this.getDay(), month = this.getMonth();
-
var hours = this.getHours(), minutes = this.getMinutes();
-
function pad(num) { return num.toPaddedString(2); };
-
-
return format.gsub(/\%([aAbBcdHImMpSwyY])/, function(part) {
-
switch(part[1]) {
-
case 'a': return $w("Sun Mon Tue Wed Thu Fri Sat")[day]; break;
-
case 'A': return $w("Sunday Monday Tuesday Wednesday Thursday Friday Saturday")[day]; break;
-
case 'b': return $w("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec")[month]; break;
-
case 'B': return $w("January February March April May June July August September October November December")[month]; break;
-
case 'c': return this.toString(); break;
-
case 'd': return pad(this.getDate()); break;
-
case 'H': return pad(hours); break;
-
case 'I': return pad((hours + 12) % 12); break;
-
case 'm': return pad(month + 1); break;
-
case 'M': return pad(minutes); break;
-
case 'p': return hours> 12 ? 'PM' : 'AM'; break;
-
case 'S': return pad(this.getSeconds()); break;
-
case 'w': return day; break;
-
case 'y': return pad(this.getFullYear() % 100); break;
-
case 'Y': return this.getFullYear().toString(); break;
-
}
-
}.bind(this));
-
}
-
});
[via Justin Palmer]
Schön gelöst. Weitere ähnliche Schnippsel von ihm gibt es im GitHub.
So wurde bisher in Prototype.js eine Klasse erstellt:
-
var Message = Class.create();
-
Message.prototype = {
-
initialize(title, message) {
-
this.title = title;
-
this.message = message;
-
},
-
format: function() {
-
return this.title + "\n" + this.message;
-
},
-
show: function() {
-
alert(this.format());
-
}
-
}
Und so haben wir diese dann erweitert, komplett mit "Variable.prototype" und "Object.extend", aber ohne wirklichen Bezug zur abgeleiteten Klasse.
-
var ErrorMessage = Class.create();
-
ErrorMessage.prototype = Object.extend(new Message(), { // überschreibe format()
-
format: function() {
-
return 'ERROR: ' + this.title + "\n" + this.message;
-
}
-
});
In Prototype 1.6 ist dass nun alles ein wenig einfacher. Anstatt noch mal mit "Variable.prototype = {...}" zu beginnen, übergeben wir den "Hash" direkt als Parameter von Class.create().
-
var Message = Class.create({
-
initialize(title, message) {
-
this.title = title;
-
this.message = message;
-
},
-
format: function() {
-
return this.title + "\n" + this.message;
-
},
-
show: function() {
-
alert(this.format());
-
}
-
});
Das Erweitern ist jetzt ähnlich PHP und liest sich fast ebenso natürlich wie "Klasse extends AndereKlasse". Wir nehmen auch hier direkt den Namen der Variable (bzw. Klassenname) anstatt "new Variable()". Hinzu kommt dass "Object.extend" komplett wegfällt. Man beachte das $super, welches die Kopie der originalen Methode ist.
-
var ErrorMessage= Class.create(Message, {
-
format: function($super) {
-
return 'ERROR: ' + $super(); // vergleichbar mit parent::format(); in PHP
-
}
-
});
Die vorherige Klasse hatte kein Parameter in der Funktion, jedoch wird $super nun definiert. Warum?
Das ist nur der Fall bei Unterklassen und ist optional. Sollte die ursprünglich Methode bereits Paremeter erwarten, sind diese dann einfach als zweiter Parameter zu definieren. Die neue Methode lässt sich dann genau wie das Original verwenden.
Hier mal ein Beispiel:
-
var notice = new Message('Nur zur Info', 'Dies ist das normale Format');
-
notice.show(); // wirft alert('Nur zur Info ...');
-
-
var error = new ErrorMessage('Es trat ein Fehler auf', 'Deshalb ein anderes Format');
-
error.show(); // wirft alert('ERROR: Es trat ein ...');
Ich habe eine Testseite angelegt und auch ein paar weitere Beispiele angefangen. Vor allem ist addMethods interessant, da es die hinzugefügten Methoden anschliessend an alle Instanzen vererbt. So könnte man zum Beispiel durch eine erfüllte Bedingung allen Klassen "auf Knopfdruck" neue Möglichkeiten einräumen (mutieren).
Naja.. schaut euch einfach mal die Tests an und ansonsten wie gehabt:
Happy coding!
Ich hab mich mal ein wenig mit Adobe AIR befasst. Die Beta soll ja auch den Webentwicklern mit HTML/JS Hintergrund entgegenkommen. Ich habe mich also ans Werk gemacht und musste feststellen das dies wirklich noch zu sehr eine Beta ist.
Es ist möglich Prototype und sonstiges Javascript zu verwenden und auch CSS Frameworks with YUI Fonts-Reset-Grids einzusetzen. Also wirklich ganz normales HTML, mit und ohne Windows Fenster drumherum. Damit hat man schon mal eine ganze Menge Freiraum! Was die Client/Server Kommunikation betrifft, kann man beliebig Ajax verwenden und natürlich auch die von AIR gebotenen Schnittstellen (windows.runtime im DOM). Auch tief verschachtelte Ordner werden von CSS und HTML ohne Probleme übernommen.
Als ich so weit war dem ganzen Leben einzuhauchen traten aber schon die ersten Probleme auf: Es wurde mein "bitte warten" GIF nicht abgespielt. Ich war ja bereit ein wenig einzustecken und komplett auf HTML und Javascript zu setzen, aber keine animierten GIFs - um es halbwegs interessant aussehen zu lassen - ist absolut inakzeptabel. Davon habe ich mich aber wenig beeindrucken lassen. Geht ja auch anders ... dachte ich.
Ich habe dann die Animation einfach in Flash umgesetzt und das SWF in das HTML mit dem üblichen Object-Tag eingefügt. Man sollte meinen dass dies klappt, wo AIR doch eigentlich zusammen mit Flex sowieso den Schwerpunkt in Flash hat. Ergebnis: Fehlanzeige! SWF Dateien werden nicht innerhalb des HTML Bereichs angezeigt. Egal mit welchen Tricks. Im Forum habe ich dann erfahren dass dies bekannt ist und mit der nächsten Version kommen soll. :-(
Okay.. Also HTML Support ist drin und läuft auf WebKit (was mehr oder minder eine gute Wahl ist), aber Animationen lassen sich nicht mit den üblichen Mitteln realisieren. Damit ist das ganze zur Zeit ziemlich sinnlos, aber für mich nicht gänzlich gestorben. Ich werde nun mal versuchen mit Flash und Flex die Sache auszuprobieren, denn Lust meine ursprüngliche Idee umzusetzen habe ich immernoch.
Es gibt ein Beta Update für Flash womit Adobe AIR integriert wird, aber auch hier nur halb! Es gibt kein Code-Hinting, was häufige Blicke in die Referenz Doku zur Folge hat. Mit ein paar Tricks kann man aber sich bis zum Adobe Integrated Runtime 1.0 Release behelfen.
Schade das der Einstieg in die AIR Entwicklung nicht so leicht war, wie erhofft.
Wer es auch mal probieren möchte sollte sich Aptana IDE besorgen. Dort ist es super integriert.
Auf Ajaxian entdeckte ich heute die sprinkle.js. Ein Skript welches das dynamische laden von Inhalten via eines Pseudoattributes "src" ermöglichen soll. Abgesehen davon dass dies nicht valide ist, da es kein "src"-Attribut für ein DIV gibt, waren die Kommentare im Gegenzug dazu doch recht erfrischend. :-)
Hier ein Beispiel wie sprinkle.js funktionieren soll:
-
<script src="sprinkle.js"></script>
-
<div src="info.html"></div>
-
<!-- info.html wird via ajax in das div geladen, on body load -->
Die sprinkle.js ist rund 300 Zeilen lang und enthält eine Menge Schönheitsfehler und ist eigentlich ein gutes Beispiel wie man es nicht machen sollte. Wem aber diese Lösung gefällt, und bereits eine Bibliothek wie Prototype oder jQuery verwendet, sollte sich mal die folgenden Beispiele ansehen.
jQuery - www.jquery.com
-
$('textarea[src], div[src], span[src]').each(function() {
-
$(this).load(this.src);
-
});
Prototype -www.prototypejs.org
-
$$('textarea[src], div[src], span[src]').each(function(el){
-
new Ajax.Updater(el, el.src||'');
-
});
Somit wäre das mit der sprinkle.js wohl dann auch geklärt ;)
Zumindest temporär(?) und es fehlen nur noch 3 Abschnitte, die man aber ruhig übersehen darf. Das Blog Tutorial und User Auth. Ich habe eine frühe Version dieser Doku bereits als PDF im Forge von CakePHP gefunden und war begeistert eine beinahe Buch-ähnliche Fassung zu haben. Nun scheint es fast komplett und beim überfliegen des Inhaltsverzeichnisses kommt es einem vor als wäre man an der richtigen Stelle für alle seine Fragen. Sehr zu empfehlen - auch wenn es noch nicht komplett ist.
Link: http://tempdocs.cakephp.org
via CakeBaker
Hmm.. ein JSON XHR mit mehr Sicherheitsfeatures klingt gut - aber wenns der User nicht hat, dann hat er einfach Pech? Verstehs nicht ganz, aber ich seh es mal als Proof of Concept. Wenn es wirklich anklang finden sollte, kann man ja immernoch darauf setzen.
via Ajaxian
Ich hab grad mal wieder eine Frage zum Safari Browser im iPhone gelesen und da fiel mir mal wieder ein, dass da ja mal was war. Ach ja - Das tolle iPhone von Apple. Das wollt ich doch mal haben ...
Mal ganz davon ab dass der Hype hier in Deutschland überhaupt nicht ankam, ist für mich mittlerweile das iPhone in Europa endgültig gestorben. Da sieht man mal wieder wie schlecht es ist ein Gerät zeitversetzt zu veröffentlichen.
Die Suppe sollte eben serviert werden solange sie noch heiss ist. Obwohl ich auch dem Apple Wahn verfallen bin, wäre ich mir gar nicht mehr sicher ob ich es noch haben will wenn es denn kommt.
Ein anderer Punkt ist auch aus der Sicht des Wettbewerbs relevant. Für mich als Entwickler hat man in dem Bereich wahrscheinlich kaum noch Chancen, denn die USA hat uns mittlerweile Monate vorraus. Klar kann man natürlich irgendwas nehmen und "eindeutschen", aber die Jungfräulichkeit fehlt eben. Hätte wirklich gerne damit rumgespielt.
Naja.. und hinzu kommt das irgendwelche Schlauberger sich alle nur erdenklichen Domains mit "iPhone" im Namen registriert haben um Kohle zu machen. So kann man natürlich auch eine Entwicklung stoppen.
Fazit für mich:
Ich hoffe Google kommt aus dem Quark und bringt ein Mobiltelefon mit UMTS, GPS und Mozilla Browser. Das wäre doch mal ein schickes Gerät. Aber wenn dann bitte zeitgleich!
PS: Wer einen angesäuerten Unterton entdeckt liegt vollkommen richtig.
Ich las grad wieder auf Ajaxian darüber und auch ich selbst steh dem oft gespalten gegenüber. Ich leuge nicht ein starker Vertreter von Prototpye.js zu sein, und wahrscheinlich werden folgende Gedanken davon geprägt sein, aber ich finde ich muss mal schreiben was ich an Prototype so wirklich mag und was ich bei jQuery vermisse.
Das Frameworks einen neuen Schreibstil mit sich bringen ist bekannt. Von den ganzen Codeschnipseln und endlosen Experimenten kann ich sagen dass Prototype einfach eleganter ist, bzw. es liest sich einfach schöner.
Ich würde zum Beispiel niemals auf die Idee kommen einen Ajax-Chat oder ein komplexes Interface mit jQuery umzusetzen, denn dort würde man (einfach um den Überblick nicht zu verlieren) Klassen und Objekte erstellen um die Anwendung in handliche Einheiten zu zerlegen. Dazu ist jQuery meiner Meinung nach einfach nicht Gedacht. Prototype wartet hierzu mit einem ganzen Arsenal von Utilities auf.
Bei jQuery gibt es viele Nebenprodukte wie $.each, die vielleicht wie eine Alternative zu Prototype erscheinen, aber auf mich eher wirken als wäre den Entwicklern später eingefallen das sie noch was vergessen haben. Aber deshalb sind es eben zwei paar Schuhe.
In jQuery dreht sich alles um Elemente (eher Sammlungen von Elementen). Es wird immer davon ausgegangen dass man mit HTML arbeitet, was meiner Meinung nach ein riesiger Nachteil von jQuery ist. Zur DOM-Manipulation bestens geeeignet (und man kann dort wirklich mächtige Ein-Zeiler schreiben), aber wenn man mit fremden Daten arbeitet kommt man schnell ins Schleudern. Dann ist plötzlich jQuery nicht mehr so toll.
Prototype hat seine stärken bei der Verarbeiten von Daten. Arrays, Hashes und Strings. Das liegt daran, weil Prototype eine ganz andere Route verfolgt. Es erweitert die vorhandnen Javascript Objekte und würzt es mit einem einfachen Modell zum Erstellen von Klassen. Es hilft einem also nicht nur schnell an irgendwelche Elemente zu kommen, sonder greift einem auch in anderen Bereichen unter die Arme.
Demnach kann man jQuery und Prototype auch gar nicht wirklich gegenüber stellen.
Bei der Frage nach Prototype oder jQuery antworte ich eigentlich deshalb meist: Wollen wir ein wenig HTML manipulieren, oder wollen wir eine Ajax-Anwendung schreiben? Letzteres wäre dann Prototype.
Man muss nur mal einen Blick in Dokumentation beider schauen. Bei Prototype gibt es für alles etwas. Bei jQuery stellt der DOM Abschrnitt alles andere in den Schatten.
Prototype kann einfach mehr und lässt einen nicht irgendwann im Dunkeln, weshalb Prototype mein Favorit für jede Anforderung ist.
Vor einiger Zeit habe ich mal mein eigenes Ajax.JSONRequest() geschrieben, weil ich kein Fan davon bin 100 mal das gleiche zu schreiben. Damit das alles klappt habe ich mich nach dem richtigen Content-Type umgesehen und den Prozess darauf aufgebaut. Der korrekte Typ ist application/json und falls gesetzt, evaluieren den responseText automatisch.
Die neue Prototype 1.6 Version nutzt ein ähnliches Prinzip und liefert uns nun ein transport.responseJSON. Vorbei sind die Zeiten von transport.responseText.evalJSON(). Ich frage mich warum nicht gleich so, wo doch text/xml schon seit längerem dafür gesorgt hat das wir responseXML haben. Naja.. super Schritt vorwärts.
-
getResponseJSON: function() {
-
var options = this.request.options;
-
try {
-
if (options.evalJSON == 'force' || (options.evalJSON &&
-
(this.getHeader('Content-type') || '').include('application/json')))
-
return this.transport.responseText.evalJSON(options.sanitizeJSON);
-
return null;
-
} catch (e) {
-
this.request.dispatchException(e);
-
}
-
}
Es gibt auch nocht ein paar neue Optionen für Ajax.Request.
- sanitizeJSON (bool) - Prüft automatisch auf böse Inhalte und blockiert die Ausführung falls etwas gefunden wird. Ist standardmässig "true", aber ob das so gut ist, weiss ich nicht. In der ersten Revision gab es Probleme je nach Anwendungsgebiet.
- evalJSON (bool) - Damit kann man das neue Verhalten der automatischen evaluierung beeinflussen. Standard ist "true" und gut.
- evalJS (bool) - Gleiches Prinzip, anderer Inhalt. Wenn der Server text/javascript liefert wird der responseText direkt ausgeführt.
Angeblich soll diese Version 1.6.0 RC_0 recht stabil sein, aber ich warte lieber und werde nach und nach die Api Doku aktualisieren.
Als ich heute so durch meine RSS Subscriptions wanderte fand ich einen Artikel bei CakeBaker wie man in einem Controller einen Helper verwenden kann. Ich stimme natürlich zu, dass es nicht immer Sinn macht und eigentlich vermieden werden sollte, aber es gibt dennoch immer Bereiche wo es sinnvoll ist.
Ich finde den TimeHelper zum Beispiel auch sehr nützlich in einer Action bzw. in einem Controller. Grad wenn man mit externen Daten arbeitet und die das Unix Format verwenden, oder zeitbasierte Queries bilden will.
Die HelperComponent nimmt einfach das von mir festgelegte Property "actionHelpers" und lädt alle dort definierten Helper in den Controller unter selben Namen. Man kann also auf die Helper so zugreifen wie auf Components.
Das nur als Beispiel. Der Rest bleibt euch überlassen ;)
app/controller/compontents/helper.php
-
class HelperComponent extends Object {
-
var $controller;
-
-
function startup(&$controller)
-
{
-
$this->controller = $controller;
-
$this->pushHelpers();
-
}
-
}
-
-
function pushHelpers()
-
{
-
foreach($this->controller->actionHelpers as $helper) {
-
loadHelper($_helper);
-
$_helperClassName = $helper.'Helper';
-
$this->controller->{$helper} = new $_helperClassName();
-
}
-
}
-
}
Viel Spass damit.

