#1 2025-06-11 17:50:58

testgary
Member
Registered: 2025-02-06
Posts: 19

Differences between backend Mustache rendering in Mormot and frontend

Differences between backend Mustache rendering in Mormot and frontend Mustache.min.js rendering:

Backend data:

{
  "Result": {
    "Data": [
      {
        "Name": "John"
      },
      {
        "Sex": "Male"
      }
    ]
  }
}

Backend Mustache rendering:

{{#Result.Data}}
  {{Name}}{{^Result.Data}}Unknown{{/Result.Data}}
{{/Result.Data}}

Frontend Mustache.min.js rendering:

{{#Result.Data}}
  {{Name}}{{^Data}}Unknown{{/Data}}
{{/Result.Data}}

One is a relative path, and the other is an absolute path
While writing the code, I found a small issue. I want to share it here so everyone can avoid spending hours troubleshooting the same problem.

Mustache.min.js is the official code I downloaded; my testing is not rigorous enough

Offline

#2 2025-06-12 06:45:59

testgary
Member
Registered: 2025-02-06
Posts: 19

Re: Differences between backend Mustache rendering in Mormot and frontend

Today I checked, and if Name is empty, the code below doesn't work at all.

{{#Result.Data}}
  {{^Result.Data.Name}}Unknown{{/Result.Data.Name}}
{{/Result.Data}}

{{#Result.Data}}
  {{^Name}}Unknown{{/Name}}
{{/Result.Data}}

Offline

#3 2025-06-12 07:10:54

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 15,049
Website

Re: Differences between backend Mustache rendering in Mormot and frontend

All this is confusing.

Mustache.min.js is somewhat official for sure, but what counts is the Mustache specification from https://github.com/mustache/spec/tree/master/specs
AFAIR we validate our engine against it.

I am not sure what the engine is supposed to do about this partial Result.Data nested references.
There are some explicit tests in https://github.com/mustache/spec/blob/m … tions.json which do pass, but your templates seem out of scope / unsupported.

TL&WR:
If someone can't understand what the template is supposed to do by reading it, then your template needs to be simplified.

Offline

#4 2025-06-12 09:43:08

testgary
Member
Registered: 2025-02-06
Posts: 19

Re: Differences between backend Mustache rendering in Mormot and frontend

I don’t know where I went wrong; the code is still not executing as I expected.

The name field in the MongoDB database is of string type and can be empty "".

{{name}} is correct — it shows empty if the value is empty, or if I write a character in the database, it displays correctly.

I am using TMVCApplication, and these templates are all placed in the frontend HTML.

{
  "Result": {
    "Data": [
      {
        "Name": ""
        "Sex": "Male"
      },
      {
        "Name": "1"
        "Sex": "Male"
      }
      {
        "Name": "2"
        "Sex": "Male"
      }
    ]
  }
}

None of the following work:

{{#if name, "=", ""}}No name{{/if}}
{{#if name =, ""}}No name{{/if}}
{{#if name,"=",""}}No name{{/if}} 
{{#if name=""}}No name{{/if}}   

{{^name}}No name{{/name}}

{{#Equals name,""}}No name{{/Equals name,""}}
{{#Equals name,""}}No name{{/Equals}}

The link you gave me, I also looked at it, but I still don't understand.
Is it that strings cannot be compared?

I wrote a RegisterExpressionHelpers myself and got it working, but I still want to understand where I went wrong.

Last edited by testgary (2025-06-12 09:55:23)

Offline

#5 2025-06-12 10:05:57

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 15,049
Website

Re: Differences between backend Mustache rendering in Mormot and frontend

Your template is not reproducible.

How do you loop into the items?

Offline

#6 2025-06-12 10:12:41

tbo
Member
Registered: 2015-04-20
Posts: 364

Re: Differences between backend Mustache rendering in Mormot and frontend

testgary wrote:

I wrote a RegisterExpressionHelpers myself and got it working, but I still want to understand where I went wrong.

Have you tested your Mustache scripts with this demo from the examples?

With best regards
Thomas

Offline

#7 Yesterday 02:29:07

testgary
Member
Registered: 2025-02-06
Posts: 19

Re: Differences between backend Mustache rendering in Mormot and frontend

I used the mvc-blog example and modified the following code in the articlerow.partial file, but the functionality did not meet my expectations:

<h2 class="blog-post-title"><a href=articleView?id={{id}}>{{Title}}</a></h2>
<h2 class="blog-post-title"><a href=articleView?id={{id}}>{{Title}}{{^Title}}000{{/Title}}</a></h2>

I just checked the mvc-blog source code and found that {{^ }} (the inverted section) is always used with Boolean, Array, or null types. It seems it’s not used with strings. Could it be that it doesn’t work with strings?

I also looked up the inverted.json file but it seems there’s no operation for empty strings.

However, if the following code is rendered on the frontend with JavaScript calling Mustache.min.js, it works fine. I guess it works because my code is similar and also rendered on the frontend:

<h2 class="blog-post-title"><a href=articleView?id={{id}}>{{Title}}{{^Title}}000{{/Title}}</a></h2>

I saw the mormot.core.mustache unit’s RenderContext code and it looks like empty strings are not supported:

procedure TSynMustache.RenderContext(Context: TSynMustacheContext;
  TagStart, TagEnd: PtrInt); 

      mtInvertedSection:
        // display section for no key, false value, or empty list
        if Context.AppendSection(t^.ValueSpace, t^.Value) <> msNothing then
        begin
          TagStart := t^.SectionOppositeIndex;
          continue; // ignore whole section
        end; 

I haven’t looked deeper into the code yet, and I might have said something wrong.

Offline

#8 Yesterday 06:19:12

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 15,049
Website

Re: Differences between backend Mustache rendering in Mormot and frontend

AFAICT void string "" exists and is not false, so should be rendered.

If the person key exists and has a non-false value, the HTML between the pound and slash will be rendered and displayed one or more times.
http://mustache.github.io/mustache.5.html

In the specs, falsey values are false, non existing or null.
https://github.com/mustache/spec/blob/m … tions.json

ChatGTP believes "" is falsey, but it hallucinates and can't explain why.

Some online testing seems to confirm that "" is true and should be rendered.
https://rickkas7.github.io/mustache/
https://stackoverflow.com/questions/747 … h-mustache

I found this official discussion, which states that it is unclear, broken, and unspecified:
https://github.com/mustache/spec/issues/28
TL&WR: the "official" solution is use an explicit boolean value in your data to avoid any confusion sad

I have made this more clear in the code:
https://github.com/synopse/mORMot2/commit/e022dee78

Offline

#9 Yesterday 11:26:42

testgary
Member
Registered: 2025-02-06
Posts: 19

Re: Differences between backend Mustache rendering in Mormot and frontend

This is really a headache-inducing issue. The Mustache official specification should resolve this problem, or we could implement this functionality directly in the Pascal code. Some online Mustache implementations already treat empty strings as true, and I think this doesn't pose any security risk because {{#section}}...{{/section}} and {{^section}}...{{/section}} are paired constructs. At least in general understanding, they are supposed to work that way; otherwise, it would truly cause confusion.

For just this small feature, I really have to write some code to handle it—it’s definitely not convenient.

Last edited by testgary (Yesterday 11:51:50)

Offline

#10 Yesterday 12:28:37

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 15,049
Website

Re: Differences between backend Mustache rendering in Mormot and frontend

AFAICT https://github.com/mustache/spec/issues/28 explains why they did not include it into the specs, and why the correct solution is to add a boolean flag like "has-name" in the input data.

See e.g. also
https://github.com/groue/GRMustache/blo … rpretation

Offline

Board footer

Powered by FluxBB