Mit Fusion definieren wir das Verhalten unserer Inhalte. Fusion erlaubt es uns Komponenten zu bauen, die wiederverwendbar sind und sich anpassen lassen. In Neos rendern wir unsere Seite mit Fusion. In diesem Kapitel soll es eine Zusammenfassung der Fusion-Grundlagen geben.
In Fusion ist so ziemlich alles ein Objekt. Egal ob eine Seite, eine Sektion, ein Button oder ein Absatz Text.
Hier ist etwas Fusion-Code zur Einstimmung:
prototype(Button) {
farbe = "#ff9999"
text = "Jetzt Kontakt aufnehmen"
link = "http://example.com/contact"
}
Die Codebeispiele hier sind stark vereinfacht und würden u.U. nicht mal funktionieren. Zum Verständnis der Funktionsweise von Fusion, sind sie aber besser als direkt in “echten” Fusion-Code einzutauchen. Dazu werden wir aber sehr bald kommen!
Sieht auf den ersten Blick ein bisschen wie ein JavaScript-Objekt mit einer leicht veränderten Syntax aus.
Im obigen Beispiel sind farbe, text und link sog. Properties des Objekts Button. Prototypes werden später erläutert.
Schonmal vorweg: Properties sind keine Variablen!
Eine Property kann auch ein Fusion-Objekt als Wert besitzen. Im nächsten Code-Beispiel wird exemplarisch ein Button-Objekt von oben als Wert de kontaktButton-Property im Banner-Prototype übergeben und direkt instanziiert.
prototype(Banner) {
beschreibung = "Hier könnte ihre Werbung stehen"
kontaktButton = Button {
farbe = "#ff9999"
text = "Jetzt Kontakt aufnehmen"
link = "http://example.com/contact"
}
}
Hier liegt auch das Grundprinzip von Fusion: Fusion-Objekte verschachteln andere Fusion-Objekte und bilden daraus praktisch einen Baum aus Fusion-Objekten.
Fusion-Objekte können auf Daten von “außerhalb” zugreifen. Diese Daten befinden sich im sogenannten Context. Der Context ist an sich eine Liste mit Variablen, welche im Baum aus Fusion-Objekten "heruntergerreicht" wird. Fusion-Objekte kommunizieren also über den Context miteinander. Ein Fusion-Objekt kann selbst Variablen im Context hinzufügen.
Wollen wir also unsere Properties in den Context einfügen (z.B. damit Kind-Objekte auf sie zugreifen können), würde das im Code so aussehen:
prototype(Button) {
farbe = "#ff9999"
@context.farbe = ${this.farbe}
}
Okay, wo kommt jetzt plötzlich das @ her und was soll das ${}? Dazu werden wir noch kommen, aber um es trotzdem kurz vorweg zu nehmen:
Fusion Prototypes sind vom Gedanken her nicht sonderlich anders als Prototypes in JavaScript. In unserem Button-Prototype haben wir einige Properties angelegt und mit Standardwerten versehen. Das bedeutet, dass jedes neue instanziierte Button-Objekt von Anfang an diese Properties besitzt. Die Standardwerte können selbstverständlich überschrieben werden.
Wie schon oben hingewiesen, kann man unsere bisherigen Codebeispiele nicht einfach so in einen Editor stecken und erwarten etwas zu sehen zu bekommen.
Probieren wir es doch einfach aus! Gehen wir dafür auf FusionPen (praktisch CodeSandbox für Fusion-Code) und schauen was passiert.
Tippen wir das obige Beispiel mit dem Button ein, tritt ein Fehler auf. Warum?
Wir verwenden ja bekanntlich Fusion um Inhalte zu rendern, also auf dem Bildschirm anzuzeigen. Was soll da ein Objekt mit irgendwelchen Properties schon machen? Was wir also brauchen, ist eine Funktionalität um Inhalte rendern zu können.
Das können wir auf zwei Wege bewerkstelligen:
In den allermeisten Fällen geht man den Weg von Punkt 2.
Bis hier hin sollen die Grundlagen erst einmal verdaut werden. Im nächsten Kapitel wird die Theorie mit konkreten Beispielen vertieft. Wir schauen was es mit dem erben von Prototypes auf sich hat und werden die Codebeispiele lauffähig machen.
Meta-Properties sind ein wichtiger Bestandteil von Fusion. Sie tauchen überall auf. Man erkennt sie durch ein vorangestelltes @. Mit Meta-Properties setzt man keine Werte sondern beeinflusst die Verarbeitung des Fusion-Objekts durch die Fusion-Runtime. Hier soll es einmal die wichtigsten Meta-Properties vorgestellt geben:
// Bsp. 1:
text = "Hier könnte Ihre Werbung stehen!"
text.@process.toUpper = ${String.toUppercase(value)}
// text hat jetzt den Wert "HIER KÖNNTE IHRE WERBUNG STEHEN!"
text.@process.replace = ${String.replace(value, "WERBUNG", "NACHRICHT")}
// text hat jetzt den Wert "HIER KÖNNTE IHRE NACHRICHT STEHEN!"
// Bsp. 2:
url.@process.convertUris = Neos.Neos:ConvertUris
// Konvertiert die url-Property zu einer öffentlich zugänglichen URL
Bis hier hin sollen die Grundlagen erst einmal verdaut werden. Im nächsten Kapitel wird die Theorie mit konkreten Beispielen vertieft. Wir schauen was es mit dem erben von Prototypes auf sich hat und werden die Codebeispiele lauffähig machen.