Skip to main content

Generating JSON

Plain JSON has no comments and no trailing commas, so a template written as JSON cannot hold a //CodeBaker: directive, and your IDE complains about every {{ }}. The way around it is to write the template as JSON5 and let CodeBaker write plain JSON.


A .json5 template, a .json file​

Name the template package.json5 and map it to package.json in the mapping file. CodeBaker reads the directives, Pebble fills in the values, and then the text is parsed as JSON5 and written again as JSON:

A .json5 template that becomes a .json file
Template.CodeBaker/package-json/
Download the template (.zip)https://codebaker.dev/examples/package-json.zip
Install in IntelliJ IDEA

Needs the CodeBaker plugin and an open project. Another IDE, or the button does nothing? Copy the link, then in the IDE right-click any folder → New → Generate from Template → Install Template from URL… and paste it. You always get a confirmation dialog before anything is installed.

codebaker.advanced.json5
{
mapping: {
// a .json5 source written to a .json name is written as plain JSON
"package.json5": "package.json",
},
}
codebaker.config.json5
{
// The folder name when the template is installed under .CodeBaker/
id: "package-json",

name: "package.json",

placeholders: ["___VAR___"],

vars: {
packageName: "my-app",
isPublic: "false",
},

json: {
tags: ["codegen", "templates"],
},
}
package.json5
// Comments are fine here: the generated package.json will not have them.
{
"name": "___packageName___",
//CodeBaker: {% if isPublic %}
"private": false,
//CodeBaker: {% else %}
"private___alt1___": true,
//CodeBaker: {% endif %}
"keywords": "{{ tags | json }}",
"version": "1.0.0",
}
Typed in the dialogstep 1, Custom Properties
packageName
my-app
isPublic
false
JSON
{
"tags": [
"codegen",
"templates"
]
}
Generated resultwhat lands in your project
package.json
{
"name": "my-app",
"private": true,
"keywords": [
"codegen",
"templates"
],
"version": "1.0.0"
}

Look at the result:

  • the comment at the top, the trailing comma and the directive lines are gone;
  • "private___alt1___" became "private": the throwaway suffix kept the two branches from being a duplicate key in the template;
  • "{{ tags | json }}" became a real JSON array (see below);
  • the keys keep their order, the indentation is two spaces, and a final line break is kept.

Everything that makes JSON5 different from JSON is converted: comments, trailing commas, keys without quotes, single-quoted strings, hexadecimal numbers (0xFF becomes 255) and the other JSON5 forms.


Choosing the format​

The conversion happens by itself whenever the source file ends in .json5 and the target file ends in .json. To say it yourself, or to switch it off, use format in the mapping entry:

formatWhat is written
not setJSON when the source is .json5 and the target is .json, otherwise the text as it is
"json"JSON, whatever the file names are
false or "json5"The text exactly as it came out, with its comments and commas
{
mapping: {
"package.json5": "package.json", // plain JSON
"tsconfig.json5": { target: "tsconfig.json", format: false }, // keeps its comments: tsconfig allows them
"settings.txt": { target: "settings.json", format: "json" }, // convert a file that is not named .json5
},
}

If the result is not valid JSON5, the generation stops with a message that names the two files, and NaN, Infinity and -Infinity, which JSON cannot hold, stop it too. format applies to ordinary files and to a seed (converted when it is written the first time). It is refused on a folder and on insert, replace and json-upsert, which merge into another file. A json-upsert entry has always written JSON: see Advanced Templates.


Lists and objects: "{{ x | json }}"​

The json filter prints a variable (a list or an object, for example from the json section of the config or an entry's data) as JSON. In a .json5 template, wrap the expression in quotes so the file stays valid in the IDE, and CodeBaker removes the quotes:

"keywords": "{{ tags | json }}",

The unwrapping applies when the whole quoted string is one expression ending in json or json(...) (other filters before it are fine), in single or double quotes, on one line. "x {{ tags | json }}" keeps its quotes. The output is pretty-printed over several lines and is not indented to match the surrounding file. For one compact line, use json(pretty=false): ["codegen","templates"].


Commas in loops: separator​

//CodeBaker: separator expands to {% if not loop.last %},{% endif %}: a comma after every item except the last. Put it right after the item:

{
"tags": [
//CodeBaker: {% for t in tags %}
"{{ t }}"//CodeBaker: separator
//CodeBaker: {% endfor %}
]
}

This writes one item per line with commas between them and none after the last, so the result is valid JSON even without the conversion. In a .json5 template that becomes .json you can simply write "{{ t }}", and keep the trailing comma, because the conversion removes it.


Next​

  • Advanced Templates: the mapping file, and json-upsert for adding entries to a JSON list that already exists.
  • Escaping Text: keep text that contains {{ }} as it is.