HTML-Bausteine zum Zusammenklicken im CMS - Property Sets in MODx Revolution

Veröffentlicht am 13. Oktober 2009

Es gibt bei Content-Management-Systemen zwei Kernprobleme: Wie hält man den Redakteuer davon ab, komplexe HTML-Dinge zu verwenden, die er besser lassen sollte (z.B. <blink>, <marquee> und Konsorten) und wie macht man es ihm gleichzeitig möglichst einfach, jene komplexen HTML-Konstruktionen einzufügen, die er wirklich verwenden soll? Für letzteres scheint die Lösung der Wahl in MODx Revolution aus dynamischen Chunks mit Property Sets zu liegen.

Chunks sind statischer HTML-Code, die aber seit MODx Revolution Platzhalter für wechselnden Content kennen. Diese notiert man als im Chunk-HTML.

<div class="graue-box">
    <h2></h2>
    <p>[[+Text]]</p>
</div>

Die Verwendung dieser Platzhalter ist wie bei Snippets via Parameter möglich. Man könnte also beim Einbinden des Chunks schreiben:

[[$GraueBox? &Headline=`Lorem Ipsum` &Text=`Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium`]]

Das Prinzip ist aus MODx seit jeher bekannt und für Nichtnerds nicht gerade komfortabel. Aber es gibt ja die Revolution tollen Drag&Drop-Funktion, mit denen man solche Konstruktionen einfach zusammenklickbar machen kann. Alles was man dazu tun muss, ist ein den Platzhaltern entsprechendes Property Set zum Chunk anzulegen. Dort gibt man an, welcher Platzhalter welchen Inhalt wiedergeben soll.

Anlegen eines Property Sets in MODx Revolution

Wenn ein Redakteur diesen Chunk nun per Drag&Drop in seinen Text befördert, poppt ein Dialog auf, in dem er den Chunk bequem konfigurieren kann:

Property-Dialog in MODx Revolution

Heraus kommt der gleiche Chunk-Code wie oben, nur dass der Redakteur sich dank des Dialogs die Verstrickung in Parameter und Sonderzeichen sparen kann. Und das Ergebnis ist trotzdem ein sauberes, standardisiertes Stück HTML. Property Sets gibt es nicht nur für Chunks, sondern für alle Contentressourcen – komplizierte Snippets lassen sich also auch auf diese Weise konfigurieren und dann einfach einfügen.

Mootools für die Massen, Teil 5: Programmieren im Mootools-Stil

Veröffentlicht am 6. August 2009

Nachdem wir in den ersten vier Teilen dieser Artikelserie die einzelnen Funktionen und Prinzipien von Mootools kennengelernt haben stellt sich nur noch die Frage: was kann man damit anstellen? Objekte, Klassen, Events und Dollarfunktionen schön und gut – doch was hat man im Programmieralltag davon? Diese Frage soll dieser letzte Teil der Serie anhand eines Beispiels aus dem Mootools-Core und einem Tutorial für ein selbstgebautes Plugin beantworten.

Was Klassen leisten können

Das Klassensystem von Mootools ermöglicht es, bestehende Funktionen zu verändern, ohne ihren Code anrühren zu müssen. Die Scripts bleiben sauber, modular und vor allem klein – ein Prinzip, das auch im gesamten Kerncode von Mootools seine Anwendung findet.

In Teil 3 der Artikelserie haben wir uns ja unter anderem die Request-Klasse angesehen, mit der sich bequem Ajax aus dem Ärmel schütteln lässt. Mootools hat mit Request.JSON auch eine abgewandelte Form dieser Request-Funktion dabei, die statt purem Text JSON verarbeitet. Dank des Klassensystems ist Request.JSON eine Sache von nicht mal 20 Zeilen Code:

Request.JSON = new Class({
    Extends: Request,
    options: {
        secure: true
    },

    initialize: function(options){
        this.parent(options);
        this.headers.extend({'Accept': 'application/json', 'X-Request': 'JSON'});
    },

    success: function(text){
        this.response.json = JSON.decode(text, this.options.secure);
        this.onSuccess(this.response.json, text);
    }

});

Einfach die Ursprungsklasse um zwei Funktionen erweitern, fertig! Ganz ohne irgendwelchen Code zu hacken oder zu duplizieren – elegant und kompakt. Dieses Prinzip kann (und sollte man) auf fast jedes seiner Mootools-Scripts anwenden.

Ein Beispiel

Setzen wir uns doch mal folgende Beispielaufgabe: ein Script soll beim Klick auf einen Link ein Fenster ähnlich dem Popup der alert()-Funktion anzeigen. Spontan würde es sich anbieten, das Fenster einfach zusammenzusetzen, indem man ein entsprechendes HTML-Element erstellt und in das Dokument einfügt:

$('link').addEvent('click', function(e){
    e.stop();
    var container = $('container');
    var popup = new Element('div', {
        'class': 'popup',
        'text': 'Das hier ist der Text unseres Popup-Fensters'
    });
    popup.inject(container);
});

Das ist ganz nett und funktioniert. Aber nehmen wir doch mal an, wir würden die gleiche Funktion in eine Klasse verpacken …

Popups mit Klasse

… dann könnte das in einem ersten Schritt so aussehen:

var Popup = new Class({
    popup: null,

    // Initialisierung
    initialize: function(popupText){
        this.popup = new Element('div', {
            'class': 'popup',
            'text': popupText
        });
    },

    // Popup anzeigen
    display: function(container){
        var container = $(container);
        this.popup.inject(container);
    }
});

// Unser schönes neues Popup-Fenster
$('link').addEvent('click', function(e){
    e.stop();
    var meinPopup = new Popup('Das hier ist der Text unseres Popup-Fensters');
    meinPopup.display('container');
});

Was ist damit gewonnen außer dass die ganze Geschichte mehr Zeilen in Anspruch nimmt? Ganz einfach: Portabilität. Wollten wir unser Popup-System in eine andere Website verwenden, könnten wir jetzt die Klasse in einer JS-Datei ablegen, diese in anderen Projekten einbinden und dann am Fließband neue Popups produzieren – pro Fenster reicht dann eine einzige Code-Zeile mit new Popup('Text').display('container'). Das Ergebnis sieht am Ende gleich aus, aber ohne Klasse müssten wir jeweils den gesamten Code aufs neue einfügen.

Wo wir schon mal eine Klasse an der Hand haben bietet es sich auch an, das Popup-Fenster gleich etwas flexibler und konfigurierbarer zu gestalten:

var Popup = new Class({

    Implements: Options,
    options: {
        'className': 'popup',
        'popupText': 'Hier fehlt Text! Bitte ändern!',
        'container': document.body
    },
    popup: null,

    // Initialisierung
    initialize: function(options){
        this.setOptions(options); (unter anderem <code>document.body</code> als Container)
        this.popup = new Element('div', {
            'class': this.options.className,
            'text': this.options.popupText
        });
    },

    // Popup anzeigen
    display: function(){
        this.popup.inject(this.options.container);
    }

});

// Unser schönes neues Popup-Fenster
$('link').addEvent('click', function(e){
    e.stop();
    var meinPopup = new Popup({
        'popupText': 'Das hier ist der Text unseres Popup-Fensters'
    }).display();
});

Jetzt ist der Code noch länger, aber dafür ist das Plugin einfacher zu verwenden, bei immer noch gleichem Ergebnis. Es kann das aus Mootools bekannte Options-Objekt verwendet werden, so dass man Klasse des Popups und auch den Text einfach an einer Stelle ändern kann. Außerdem haben wir unter options Standardwerte für alle Werte notiert, so dass man bei Bedarf auch einfach new Popup.display() schreiben und trotzdem ein funktionierendes Ergebnis bekommen könnte.

Jetzt kann man die Popup-Klasse bequem in jedem Mootools-Projekt einsetzen, in dem man Popups braucht. Der Code ist portabel und flexibel. Nun könnte man sowas ähnliches vielleicht auch mit einfachen Funktionen hinbekommen, aber Mootools kann ja noch mehr.

Pimp my Popup

Unterschiedliche Websites brauchen ähnliche, aber nie ganz identische Funktionen. Deswegen ist Otto Normalwebworker oft damit beschäftigt, alten Code aus Website A in Website B zu kopieren und anzupassen. An genau dieser Stelle kann Mootools auftrumpfen – denn wir können ja unsere Klassen erweitern, ohne irgendwelchen alten Code hacken zu müssen.

Nehmen wir mal an, wir bräuchten für eine andere Website Popups mit Titelleisten und einem OK-Button um das Popup zu schließen. Die können wir ganz einfach kriegen, indem wir entsprechende Methoden in unser bewährtes Popup implementieren:

Popup.implement({

    // Eine zusätzliche Titelleiste
    addTitle: function(text){
        var titleBar = new Element('div', {
            'class': 'popupTitle',
            'text': text
        });
        titleBar.inject(this.popup, 'top');
    },

    // Und ein OK-Button
    addButton: function(text){
        var button = new Element('div', {
            'class': 'popupButton',
            'text': text
        });
        Popup.implement(Events);
        button.addEvent('click', function(){
            this.popup.destroy();
        }.bind(this));
        button.inject(this.popup, 'bottom');
    }

});

// Unser schönes neues Popup-Fenster
$('link').addEvent('click', function(e){
    e.stop();
    var meinPopup = new Popup({
        'popupText': 'Das hier ist der Text unseres Popup-Fensters'
    });
    meinPopup.addTitle('Wichtige Meldung');
    meinPopup.addButton('OK');
    meinPopup.display();
});

Damit ist unser kleines Popup ganz schön aufgemotzt – ohne dass wir ein Byte an unserer Ursprungsklasse verändern mussten. Und wenn wir wollten, könnten wir immer noch die ursprünglichen Popups ohne Extras erzeugen.

Popups der nächsten Generation

Ein verbessertes Popup-Fenster

Wenn man Erweiterungen einbaut, von denen man glaubt dass man sie später bei anderen Projekten nochmal gebrauchen kann, bietet es sich natürlich an, die Erweiterungen ihrerseits in eine Klasse zu packen, die die normale Popup-Klasse erweitert. Drag & Drop, Lightbox-Effekt und Minimieren-Button – das kann man alles umsetzen, ohne die Ursprungsklasse zu verändern.

var FancyPopup = new Class({
    Extends: Popup,
    // Code für die zusätzlichen Funktionen
});

var meinPopup = new FancyPopup({
    'popupText': 'Das hier ist der Text unseres Popup-Fensters'
});
meinPopup.addTitle('Wichtige Meldung');
meinPopup.addButton('OK');
meinPopup.addOverlay();
meinPopup.display();

Und die Erweiterungen selbst sind wieder in einer handlichen Klasse zusammengefasst, die man ihrerseits in andere Projekte portieren und dort noch mehr erweitern kann.

The Art of Moo

Die Kunst des Mootools-Programmierens liegt also einfach darin, Scripts so zu gestalten, dass sie entweder erweiterbar sind oder ihrerseits auf vorhandenen Scripts aufbauen. Das Klassensystem von Mootools macht dieses Vorhaben in der Sache einfach – man muss nur ein gewisses Maß an planerischer Weitsicht aufbringen.

Wenn man immer fleißig Klassen anlegt, baut man sich in kurzer Zeit einen Fundus an Plugins auf, die portabel und im Bedarfsfall einfach erweiterbar sind, wobei die Erweiterungen ihrerseits wiederum portabel und erweiterbar sind. Die Klassen sind zwar von der Codemenge her alle etwas länger als wenn man einfach ständig $().foo().bar() schreiben würde, aber bereits bei der ersten Portierung in ein anderes Projekt macht sich das bezahlt. Und bei der ersten Erweiterung mit einem einfachen Extend erst recht.

Und als Bonus kommt eben noch hinzu, dass man nicht alles in Klassen verpacken muss. Man kann das tun und sollte es in 90% der Fälle sicher auch tun, aber wenn man nur eben mal schnell etwas zusammenhauen möchte, geht das auch: $('foo').fade('out'); funktioniert in Mootools genau so wie bei jQuery und Konsorten. Mootools macht die einfachen Dinge einfach, hat aber auch (und vor allem) für die komplexeren Dinge alle nötigen Funktionen auf Lager. Und genau das ist der Grund, warum dieses schöne kleine Javascript-Framework unsere Aufmerksamkeit verdient.

Mootools für die Massen, Teil 4: Klassen erstellen und erweitern

Veröffentlicht am 3. August 2009

Nachdem wir im vergangenen Teil der Serie gesehen haben wie man Mootoools-Objekte benutzt, wird es Zeit, sich um die Erstellung eigener Klassen zu kümmern. Dieser Artikel soll das Klassen- und Vererbungssystem in seinen Grundzügen darstellen. Wer objektorientierte Programmierung kennt, sollte sich diesbezüglich schnell zurechtfinden. Was man mit den Klassen tolles anstellen kann, soll dann Bestandteil des nächsten Teils sein.

Klassen erstellen

Die Klassen in Mootools lassen sich genau so verwenden, wie man es aus anderen (richtigen) objektorientierten Programmiersprachen kennt. Ein simples Beispiel:

var Huhn = new Class({
    pick: function(){
        alert('Pick, pick!')
    }
});

So sieht die simpelste Form einer Mootools-Klasse aus. Unsere neue Klasse Huhn hat mit pick() eine Methode, die sich genau so aufrufen lässt, wie man das von anderen Objekten kennt:

var meinHuhn = new Huhn();
meinHuhn.pick(); // Alert: Pick, pick!

Klassen erweitern

Will man eine bestehende Klasse erweitern, muss man nur in der Extends-Eigenschaft entsprechend notieren:

var Hahn = new Class({
    Extends: Huhn,
    kraeh: function(){
        alert('Kikeriki!');
    }
});

Die Klasse Hahn erbt von der Klasse Huhn alle Eigenschaften und Methoden – in diesem Fall die pick()-Methode. Zusätzlich bringt Hahn noch seine eigene kraeh()-Methode mit:

var meinHahn = new Hahn();
meinHahn.pick();  // Alert: Pick, pick!
meinHahn.kraeh(); // Alert: Kikeriki!

Optionen benutzen

Um in die eigenen Klassen Funktionen aus anderen Klassen nutzbar zu machen, bietet sich die Implements-Eigenschaft an. In diesem Fall wird die Options-Klasse implementiert, die es uns erlaubt, unsere Klassen mit zusätzlichen Optionen zu initialisieren.

var Henne = new Class({
    Extends: Huhn,
    Implements: Options,
    options: {
        startEier: 2
    },
    eier: 0,
    initialize: function(options){
        this.setOptions(options);
        this.eier = this.options.startEier;
    },
    legeEi: function(){
        this.eier++;
    },
    zaehleEier: function(){
        alert(this.eier);
    }
});

Die Henne-Klasse erweitert die Huhn-Klasse und erbt dadurch die pick()-Methode. Sie implementiert die Options-Klasse und macht sich damit die setOptions()-Methode zu Eigen. Außerdem hat Henne mit initialize() eine Constructor-Funktion, die die Variablen verarbeitet, die beim Erstellen der Klasse übergeben werden.

Henne hat mit startEier eine Option, die festlegt, wie viele Eier unser Federvieh als Startkapital bekommt. In der Klasse selbst ist in der 4. Zeile ein Standardwert (2) notiert, der von initialize() überschrieben wird. Das sieht in der Praxis dann so aus:

meineHenne = new Henne();
meineHenne.zaehleEier(); // Alert: 2 (Standardwert)

var meineAndereHenne = new Henne({
    startEier: 5
});
meineAndereHenne.zaehleEier(); // Alert: 5

Die Anzahl der Eier wird in der internen Variable eier gespeichert. Mit der legeEi()-Methode erhöht man den internen Ei-Counter um eins, während der Startwert weiterhin unter options.startEier zu finden ist:

var meineHenne = new Henne({
    startEier: 7
});
meineHenne.legeEi();
meineHenne.legeEi();
meineHenne.zaehleEier(); // Alert: 9
alert(meineHenne.options.startEier); // Alert: 7

Zusätzliche Methoden implementieren

In jede bestehende Klasse kann man nachträglich zusätzliche Methoden implementieren:

Huhn.implement({
    scharr: function(){
        alert('Scharr, scharr!');
    }
});
var meinHuhn = new Huhn();
meinHuhn.scharr(); // Alert: Scharr, scharr

All das geht auch mit den Standardklassen von Mootools! Um mal ein Beispiel ohne Hühner zu nehmen, implementieren wir doch einfach mal eine Methode in die Element-Klasse (die Klasse für alle HTML-Elemente), die die betroffenen Elemente komplett leer macht:

// Vorher: <div id="meinDiv">Ein <code>DIV</code> voller HTML!</div>
Element.implement({
    empty: function(){
        this.set('html', '');
    }
});
$('meinDiv').empty();
// Nacher: <div id="meinDiv"></div>

Und weil, wir erinnern uns, alles in Mootools aus Objekten und Klassen besteht, können wir auch alles im Framework nach unserem Geschmack umkrempeln oder als Basis für eigene Kassen verwenden.

Und wozu das Ganze?

Nun ist es ja ganz nett, dass man Klassen erstellen und modifizieren kann, aber es drängt sich natürlich die Frage auf, wie man das Ganze effektiv nutzen kann. Im nächsten Teil der Serie werden wir wieder tutorialartig ein Beispiel durchgehen, das verdeutlichen wird, wie man sich mit Mootools-Klassen viel Arbeit ersparen kann.

Mootools für die Massen, Teil 3: Ein Tutorial mit Objekten

Veröffentlicht am 31. Juli 2009

Nachdem wir in den letzten Teilen der Serie die Basics hinter uns gebracht haben, geht es heute um die eigentlichen Bausteine des Mootools-Frameworks: Objekte. Mootools ist objektorientiert und wir schauen uns in diesem Teil der Serie an, wie man diese verwendet. Außerdem exerzieren wir damit ein Tutorial durch, an dessen Ende wir ein Script mit Ajax- und Drag&Drop-Funktionen geschrieben haben werden – in nur 11 Zeilen Mootools-Code.

Mootools und Objekte

So gut wie alles in Mootools ist ein Objekt – Plugins, HTML-Elemente, Ajax-Requests, der JSON-Parser und alles andere. Elemente werden in Mootools mit new erstellt und haben wie ganz normale Javascript-Objekte Eigenschaften und Methoden. Ein Beispiel:

// Wir erstellen ein neues Div mit der Klasse
// "foobar" und ein paar Inline-Styles
var meinDiv = new Element('div', {
    'class': 'foobar',
    'text': 'Das ist ein ganz tolles, neues Div!',
    'styles': {
        'font-weight': 'bold',
        'margin': '1em'
    }
});

// Die "inject()"-Methode des Div-Objekts fügt das
// Element in ein anderes Element ein
var meinAnderesDiv = $('meinAnderesDiv');
meinDiv.inject(meinAnderesDiv);

So läuft es bei Mootools mit allem – auch mit Effekten. Der eine oder andere mag sich an dieses Code-Beispiel aus dem letzten Teil der Artikelserie erinnern:

// Das Element mit der Mootools-Fade-Methode ausblenden
$('foo').fade('out');

Der Fade-Effekt an dieser Stelle hier sieht nicht nach einem Objekt aus, oder? Das ist aber auch nur so, weil die fade()-Methode von HTML-Elementen als eine handliche Abkürzung für das eigentliche Effekte-Objekt ist. Für Effekte wie eine einfache Überblendung ist das Fx.Tween-Objekt zuständig, das in voller Pracht so aussieht:

// Element auswählen
var meinElement = $('meinDiv');

// Effekt-Objekt erstellen
var meinEffekt = new Fx.Tween(meinElement, {
    'duration': 500
});

// Effekt starten!
meinEffekt.start('opacity', 1, 0);

Das ist etwas mehr zu tippen als meinElement.fade(), macht aber auch mehr möglich, denn dem Fx.Tween-Objekt kann man eine Reihe nützlicher Optionen mitgeben. So lässt sich der Effekt fein steuern – im Beispiel wird die Dauer des Ausfadens auf 500ms festgelegt, aber man kann auf diese auch Effekte koppeln, die Framerate festlegen und Events nutzen.

Kurz gesagt: Objekte sind bei Mootools die Bausteine des Frameworks. Für einige Funktionen gibt es Abkürzungen, aber ohne Objekte geht es nicht. Und das ist auch gut so.

Ein etwas komplexeres Beispiel

Gregor hat sich in den Kommentaren zum letzten Teil der Serie ein Code-Beispiel gewünscht, das Drag&Drop verwendet und die Position der durch die Gegend gedragten Elements per Ajax abspeichert. Nichts leichter als das!

Zuerst brauchen wir das Mootools-Plugin für Drag&Drop. Das nennt sich schlicht und ergreifend Drag und ist im More Builder, der Download-Seite für Plugins aus der More-Komponente von Mootools, zu beziehen. Für Ajax brauchen wir nichts weiter, denn das Request-Objekt ist Bestandteil der Core-Komponente. Folgendes HTML soll den Rahmen für unser kleines Tutorial darstellen:

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="content-type" content="text/html; charset=UTF-8">
        <title>Test</title>
        <style type="text/css">
            body, html { height:100%; width:100%; margin:0; padding:0; }
            #drag { background:#000; color:#FFF; cursor:pointer; width:100px; position:absolute; top:0; left:0; padding:8px; }
        </style>
        <script type="text/javascript" src="mootools-1.2.3-core-yc.js"></script>
        <script type="text/javascript" src="mootools-1.2.3.1-more.js"></script>
        <script type="text/javascript">
            window.addEvent('domready', function(){
                // Hier kommt unser Code hin
            });
        </script>
    </head>
    <body>
        <div id="drag">Zieh mich!</div>
    </body>
</html>

Als nächstes erstellen wir das Objekt für die Drag-Funktion. Zusätzliche Optionen sind erst mal nicht nötig, also erstellen wir einfach ein Drag für das Div mit der ID drag.

var tutorialDrag = new Drag('drag');

Was man hier schön sieht, ist dass Drag (wie die meisten Plugins) eine eingebaute Dollar-Funktion hat, d.h. man muss ein HTML-Element, das man an ein Plugin übergeben will, nicht vorher mit $() oder $$() ausgewählt haben. Man kann das machen, kann aber genau so gut einfach die ID als String übergeben.

Nächster Schritt: das Request-Objekt für die Ajax-Funktion.

var tutorialRequest = new Request({
    url: 'save.php'
});

Hier müssen wir die Zieladresse für den Request als Option url mitgeben. Die Datei save.php wird das Speichern der Position des Objekts übernehmen.

Nun müssen wir das Drag- und das Request-Objekt so verzahnen, dass der Request ausgelöst wird, wenn unser Zieh-mich-Div verschoben wurde. Praktischerweise hat Drag ein complete-Event, mit dem wir eine Funktion auslösen können, sobald der Benutzer sein Verschieben abgeschlossen hat. Also bauen wir unser Drag-Objekt entsprechend um:

var tutorialDrag = new Drag('drag', {
    onComplete: function(){
        tutorialRequest.send();
    }
});

Damit rufen wir die send()-Methode des Request-Objekts aus, die die Ajax-Anfrage abschickt. Einziges Problem dabei: Wir haben noch gar keine Daten, die wir speichern könnten. Was wir hierfür brauchen sind die X- und Y-Koordinaten des Drag-Divs, die wir mit der getPosition-Methode abfragen können. Und weil das complete-Event des Drag-Objekts das verschobene Element selbst mitübergibt, können wir es uns recht einfach machen:

var tutorialDrag = new Drag('drag', {
    onComplete:function(el){
        var pos = el.getPosition();
        tutorialRequest.send();
    }
});

Die pos-Variable enthält jetzt ein Objekt mit den X- und Y-Koordinaten unseres Divs:

{
    x: 47,
    y: 175
}

Das naheliegendste wäre, dieses Objekt für die Speicherung in einen JSON-String zu verwandeln, was mit dem JSON-Encoder von Mootools denkbar einfach ist. Das Ergebnis senden wir dann in Form eines Querys mit der send()-Methode des Request-Objekts.

var tutorialDrag = new Drag('drag', {
    onComplete: function(el){
        var pos = el.getPosition();
        tutorialRequest.send('pos=' + JSON.encode(pos));
    }
});

Und damit sind wir eigentlich fertig. Wir haben ein komplettes, JSON verwendendes Drag&Drop-Ajax-Script in 11 Zeilen gebaut:

window.addEvent('domready', function(){
    var tutorialDrag = new Drag('drag', {
        onComplete:function(el){
            var pos = el.getPosition();
            tutorialRequest.send('pos=' + JSON.encode(pos));
        }
    });
    var tutorialRequest = new Request({
        url: 'save.php'
    });
});

Was jetzt noch fehlt ist das PHP zum bearbeiten des Ajax-Requests …

// save.php
if($_POST['pos']){
    if($fp = fopen('position.txt', 'w')){
        fwrite($fp, $_POST['pos']);
        fclose($fp);
    }
}

… und zum Auslesen der Koordinaten beim Laden der Seite:

// Auslesen der Daten in der HTML-Datei
$style = '';
if($fp = fopen('position.txt', 'r')){
    $line = fgets($fp, 100);
    $dimensions = json_decode(stripslashes($line));
    if($dimensions->x && $dimensions->y){
        $style = 'style="top:'.$dimensions->y.'px; left:'.$dimensions->x.'px;"';
    }
    fclose($fp);
}
<div <?php echo $style; ?> id="drag">Zieh mich!</div>

Es funktioniert! Nach jedem Neuladen der Seite ist das Drag-Element wieder an genau der Stelle, wo man es gelassen hat (jedenfalls so lange nicht mehrere Leute gleichzeitig daran herumspielen). Das gesamte Script gibt es auch gezippt zum Download.

Fazit und Ausblick

Dieses kleine Tutorial hat ganz gut zwei Eigenschaften von Mootools demonstriert:

  1. Alles ist ein Objekt
  2. Der Code ist ausgesprochen kompakt

Aber auch das ist nicht die wahre Stärke von Mootools – richtig gut wird es erst, wenn man selbst anfängt Plugins zu schreiben oder bestehende Plugins zu erweitern. Darum soll es dann im nächsten Teil gehen. Wer für diesen Teil 4 Sonderwünsche hat, der möge sie in den Kommentaren hinterlassen.