Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to render a JSON template using mustache

Tags:

json

mustache

I'm trying to generate a JSON file with mustache with the following template:

{
    "name": "{{customer_info.first_name}}",
    "email": "{{contact_info.email}}",
    "campaign": {
        "campaignId": "{{contact_info.campaign.campaignId}}"
    },
    "tags": [
        {{#contact_info.tags}} 
        {
            "tagId": "{{tagId}}"
        },
        {{/contact_info.tags}}
    ]
}

As an output example I get:

{
    "name": "Antonio",
    "email": "[email protected]",
    "campaign": {
        "campaignId": "pfft"
    },
    "tags": [
        {
            "tagId": "6prrtAP"
        },
        {
            "tagId": "64rrrE9"
        },
    ]
}

Which unluckily is a BAD FORMATTED JSON, because there is a not wanted "," after the last element in the array.

Can any of you help me in solving this issue and remove the comma ?

Thanks a lot

like image 330
AntLomb Avatar asked Nov 02 '17 19:11

AntLomb


People also ask

What is JSON mustache?

Mustache is a library that allows you to read in JSON formatted data and display it using templates you design. Mustache can be used for HTML, config files, source code – anything. It works by expanding tags in a template using values provided in a hash or object.

How do I render a mustache in HTML?

render = function (template, view, partials) { return this. compile(template)(view, partials); }; This is the most basic form of templating with mustache. Let's see the other methods available for creating more organized code.

What does mustache render do?

Mustache is a simple web template system. It is available for many programming languages including JavaScript and Java. Mustache is described as a logic-less template engine because it does not have any explicit control flow statements, such as if and else conditionals or for loops.

Is mustache a template engine?

Mustache is a logicless template engine for creating dynamic content like HTML, configuration files among other things.


4 Answers

I would do this:

var md = {};
var tagsCount = 2;
var currTagIndex = 0;
md['show_comma'] = function(){
    currTagIndex++;
    return currTagIndex <= tagsCount;
}

Then in Mustache template:

{{#show_comma}}
,
{{/show_comma}}
like image 76
MohamedSanaulla Avatar answered Nov 15 '22 05:11

MohamedSanaulla


I've been experiencing some similar problem and I found out that Handlebars is a lot similar to mustache and way more powerful.

You could check that out and try using this template to solve your problem, without adding anything to your current model.

{
    "name": "{{customer_info.first_name}}",
    "email": "{{contact_info.email}}",
    "campaign": {
        "campaignId": "{{contact_info.campaign.campaignId}}"
    },
    "tags": [
        {{#each contact_info.tags}} 
        {
            "tagId": "{{tagId}}"
        }{{#unless @last}},{{/unless}}
        {{/each}}
    ]
}
like image 26
oniramarf Avatar answered Nov 15 '22 05:11

oniramarf


Try using SelectTransform npm package. It has Mustache like syntax without all the side-effects that Mustache creates and the package size is also not as heavy as Handlebars.js

import ST from "stjs";
 
const data = {
  name: 'Jakub',
  friends: [
    {
      name: 'Michal'
    }
  ]
};
 
const template = {
  newName: '{{ name }}',
  friends: {
    '{{ #each friends }}': {
      subName: '{{ name }}'
    }
  }
};
 
console.log(ST.select(data).transformWith(template).root());
 
// Result:
/**
 * {
 *   "newName": "Jakub",
 *   "friends": [
 *     {
 *       "subName": "Michal"
 *     }
 *   ]
 * }
 */
like image 42
theSereneRebel Avatar answered Nov 15 '22 04:11

theSereneRebel


Don't generate JSON from textual templates. You'll constantly face problems like this. Superfluous commas, meta characters in strings (what if customer_info.first_name contains double quotes), failing to properly nest structures etc.

Generate your data as native structures in your programming language, and encode it as JSON using library provided by your programming language.


However, if you absolutely need, try to generate as much JSON data as possible (ideally, self-contained JSON fragment) outside template, and interpolate that inside template. For example:

let contact_info = {"tags": [ "6prrtAP", "64rrrE9" ]}
let tags = contact_info.tags.map((tag) => ({"tagId": tag})); // [{tagId: "6prrtAP"}, {tagId: "64rrrE9"}]
let tagsJSON = JSON.stringify(tags); // "[{\"tagId\":\"6prrtAP\"},{\"tagId\":\"64rrrE9\"}]"

Then, pass tagsJSON to your template:

{
    "name": "{{customer_info.first_name}}",
    "email": "{{contact_info.email}}",
    "campaign": {
        "campaignId": "{{contact_info.campaign.campaignId}}"
    },
    "tags": {{tagsJSON}}
}

That way, tagsJSON always contains valid JSON-encoded data, so it might be safely interpolated as a value in JSON dictionary/object. Even if tag list is empty, even if tag IDs suddenly start to contain characters that need escaping etc. All corner cases are already handled for you.

like image 27
el.pescado - нет войне Avatar answered Nov 15 '22 05:11

el.pescado - нет войне