Open stefanr opened 1 year ago
@stefanr Thank you for the issue report. However, I would say, this is not a bug. It is how it is worked and documentented.
{}
are fluid specific chars which marks the start end end of variables or inline code. So they have a special meaning.
You are trying to mix this some how. There are multiple ways to mitigate this, which are already documentend and explained, at least for the TYPO3 world here:
https://docs.typo3.org/m/typo3/guide-extbasefluid/main/en-us/Fluid/ThingsToKnow/JsAndInline.html
Granted, the context describes it for inline javascript, but this also counts for "json" or "JavaScript object like" markup creation.
It's a casual issue if you deal with kind of a parsed language, that special meaning chars needs to be escaped in the one or other way.
Not tested, but I guess following "should" work.
<f:variable name="test" value="foo" />
<f:format.cdata>
<div
x-data="{
test: null,
init() {
test = 'foo';
}
}"
>
</f:format.cdata>
{test}
</div>
You could also wrapp the {
and }
of your "markup" code which should not be parsed into the format.raw viewhelper (also described in the link documentation page above).
Another solution is to create a custom viewhelper which creates the "data attribute" content and the structure instead of dealing wiht the definition in the markup if possible. Otherwise, I guess the cdata approav is the "best" way to do it as it avoids a lot of char based wrappings/escapings.
@sbuerk while agreeing on the {}
special meaning I still think there's something going on. It seems like there's a randomness factor in this issue. I have a template with 1 x-data
attribute, an x-bind:class
attribute and those 2 attributes:
x-on:keyup.tab="<f:format.raw>Alpine.$data($el).__open()</f:format.raw>"
x-on:mouseup="<f:format.raw>Alpine.$data($el).__open()</f:format.raw>"
The following happens:
None of the attribute values wrapped: Simple inline var {foo}
is not replace and rendered as {foo}
Only x-data wrapped, or x-data and the x-on:keyup.tab wrap: Same result
x-data and both of the attributes above wrapped: All works fine!
x-data wrapped and both attributes fully removed: Broken again
x-data wrapped and the x-class:bind wrapped, the attributes without wrapping: Also works fine
So although the issue does not occur when all json is wrapped it still feels like the bug appears quite randomly depending on the structure / formatting of the template... also seen it in other templates where just changing indent prevented the issue from occur... So maybe this actually deserves some love...
Another issue I've noticed is when adding a comment right after the opening brackets of a function such as here:
{f:security.nonce()}
<script>
let map;
function initMap() {
// Map
map = new Map(document.getElementById("map"), {
zoom: 14,
});
}
initMap();
</script>
This causes {f:security.nonce()}
not to be parsed. However, upon removing the //Map
comment the viewhelper is correctly parsed.
@AlexanderT8 In this case, you can probably wrap your inline script in a CDATA section.
I would also say that you should extract longer scripts to a separate file and create some kind of API to provide data from the DOM (like JSON in a data attribute).
@s2b I feel like there's loads of arguments against facing this is an actual bug... Of course this can be done in an API and longer scripts can be separated, but the parsing of Fluid simply breaks... Just focus on that fact...
I myself worked around the issue with workarounds like you suggest. But that doesn't mean the parsing ain't broken... I always loved Fluid and have an actual background in contribution but I decided to drop it because it simply doesn't work in this usecase at all. Unfortunately there're better alternatives that fit the usecase with for example alpinejs better. Which probably ain't a bad thing as we've to pick the right tool for the job of course. But still I would've loved to stick to Fluid...
@radmiraal Don't get me wrong, I acknowledge that this is a problem. I also know about the alternatives to Fluid and how they handle this. I just wanted to show the workarounds once again to "solve" the problem for the example given.
Currently, curly braces are an integral part of the Fluid syntax, and I fear that it won't be easy to modify/extend this without it being a breaking change. Currently, we're working on improving the ViewHelpers and improving the test coverage to be able to make bigger changes in the future. I hope that this issue will be such a change.
Actually this is also currently in the TYPO3 Core with the SystemEmail and inline CSS. I just wasted a lot of time simply because of this bug and even the core does it wrong! :rage: See https://github.com/TYPO3/typo3/blob/f947cbc75fb899b6179ad89cc25044c0d4746ebe/typo3/sysext/core/Resources/Private/Layouts/SystemEmail.html#L16-L323
I added a custom variable and was wondering why it was NOT printed even though the backgroundColor from typo3.systemConfiguration.backend.loginHighlightColor
was working.
Sometimes when using curly braces for inline javascript or css styles inside a fluid template the parser breaks and does not further resolve variables from this point up until some other view helper is used via xml syntax or the scope (section, partial, ...) is closed.
I didn't look into the implementation in detail so it currently seems a little "random" at which point the parser stops working.
Example:
This correctly (or let's say as expected), gives:
foo
This on the other hand (focus on the indentation):
... renders as:
{test}
Placing a view helper before the variable output seems to fix wrong parser state:
... renders again:
foo
Any ideas? This issue is kind of a problem as one might not expect to destroy the following template code by changing some attributes that also render completely fine in the frontend.
Wrapping the problematic blocks like so
x-data="<f:format.raw>{ ... }</f:format.raw>"
is the current work around to fix this issue.