JavaScript Code in Fluid richtig escapen
Bist du schon einmal auf das Problem gestoßen, dass dein JavaScript Code in Fluid nicht richtig escapen wollte? Dann lese weiter...
In der Frontendentwicklung von TYPO3 kommt man früher oder später in die Situation, JavaScript Code in Fluid einzufügen. Das ist mittlerweile auch nicht unüblich und oft auch sehr sinnvoll.
Wie kann man, JavaScript Code in TYPO3 einfügen?
Mithilfe des ViewHelpers: Asset kann man gezielt CSS und JavaScript Code in ein Template einfügen, dann und wo es gebraucht wird. Das ist der große Vorteil gegebenüber dem Einfügen über das PAGE - Objekt in TypoScript.
Die Resourcen im PAGE - Objekt werden eingefügt, wenn die TYPO3 Seite dargestellt werden soll, aber nicht notwendigerweise, wenn diese Dateien auch wirklich gebraucht werden.
Mit dem <f:asset.script> oder <f:asset.css> ist das anders. Diese fügst du direkt in dein Template ein und das kannst du in den Template- oder Partialdateien machen, in denen dieser Code wirklich gebraucht wird.
Das Escaping Problem mit JavaScript in Fluid
Es kann notwendig sein, dass du Informationen von TYPO3 in dein JavaScript Code übergeben möchtest. Das können Stringwerte von Fluidvariablen sein oder das Ausführen von Fluid ViewHelpern.
Ein klassisches Beispiel ist es ein jQuery Plugin mit Informationen aus dem Controller über Fluid zu füttern. Das kann dann wie folgt aussehen:
var example1 = {
param1: "{example1.param1}",
param2: "{example1.param2}"
};
$(document).ready(function(){
console.debug(example1);
});
Das ist ein ganz einfacher und normaler JavaScript - Code, wo eine Hilfsvariable: example1 erstellt wird und Werte aus Fluid mittels der Fluidvariable: example1 zugewiesen wird.
Das Problem ist, dass Fluid zur Kennzeichnung der Fluidvariablen geschwungene Klammern nutzt. Diese geschwungenen Klammern kommen allerdings auch in ganz normalen JavaScript Code vor.
Und das ist das Problem
Der Fluidparser kann aber einer bestimmten Komplexität nicht mehr unterscheiden, welche geschwungenen Klammern zu JavaScript oder Fluid gehört.
Das Ergebnis ist, dass Fluidvariablen nicht mehr ausgegeben werden, sondern der Platzhalter: {example1.param1} als Text im HTML erscheint.
So erstellst du konfliktfreien JavaScript Code in Fluid
Damit wir kein Problem mit JavaScript und Fluid Steuerzeichen bekommen, nutzen wir den Fluid ViewHelper Variable oder Alias um alle geschwungenen Klammern, die zu JavaScript gehören zu entfernen.
In dem kommenden Beispiel wird der ViewHelper Alias genutzt. Dieser hat den Vorteil gegenüber Variable, dass die definierten Fluidvariablen nur innerhalb des Alias Tags gültig sind. Das reduziert das Konfliktpotential in Fluid.
<f:asset.script identifier="javascript-escaping-exampe">
<f:alias map="{ocb: '{', ccb: '}'}">
var example1 = {ocb}
param1: "{example1.param1}",
param2: "{example1.param2}"
{ccb};
$(document).ready(function(){ocb}
console.debug(example1);
{ccb});
</f:alias>
</f:asset.script>
Der Trick ist, dass wir die öffnenden und schließenden geschwungenen Klammern temporär in Fluid-Variablen speichern. Die öffenen Klammern speichern für unter {ocb} und die schließenden Klammern unter {ccb}.
Genial oder?
Dadurch verhindern wir, dass der Fluid-Parser Probleme bekommt zu entscheiden, wann JavaScript Code erscheint und wann nicht. Denn so ist für den Fluid - Parser alles Fluid.
Fazit
Ich habe wirklich lange Zeit mich mit CDATA und anderen Workarounds herumgeschlagen, um das Problem zwischen JavaScript und Fluid in den Griff zu bekommen.
Der obige Trick ist so einfach, wie genial und funktioniert bei mir mit Abstand am besten.