Skip to main content

Configuration Reference

Reference for codebaker.config.json5, the file that describes your template: its name, variables, where it is offered, and what happens after generation. Every template should have it: it is needed for variables and for installing a template from a link. A folder without it is still listed in the menu under its folder name, but it has no variables and cannot be installed from a link. (The mapping file, codebaker.advanced.json5, has its own pages, starting with Advanced Templates.)


Keys at a glance​

Key and typeDefaultWhat it doesIf it is wrong
name
string
the folder nameThe name in New → Generate from TemplateMissing: the menu shows the folder name
id
string
name, then the archive's file name, then templateThe folder name when the template is installed from a linkAn unusable id is cleaned up, and if nothing is left the next fallback is used; the installer says so
version
string
noneShown in the menu and recorded in the run historyText that is not a version is shown as written and is not compared on update
vars
object of strings
no fieldsOne text field in the dialog per entry, with the value as its defaultArrays and objects are dropped silently; a value that uses a variable defined below it renders as empty text
json
object
noneLists and objects; its top-level keys become variablesInvalid JSON: a red message under the JSON area, and Next stays disabled. Not an object: shown, but adds no variables
placeholders
array of strings
noneDeclares placeholder styles such as ___VAR___A style without VAR is ignored; a style that is not listed does nothing
syntax
string or object
"curly"Other Pebble delimiters for the whole templateRefused before the dialog opens, with a message that lists every problem
paths
object
offered in every folderWhere the template is offered in the menuAn unsupported pattern leaves the template out of the menu, with a warning balloon
replace
object
nonePlain text replaced everywhere before variables are appliedA key that matches nothing does nothing
ignore
array of strings
only the config files and .historyTemplate files that are not generatednotes/** does not match the folder notes itself: list both
open
array of strings
nothing is openedFiles to open after generationA file that does not exist is skipped
expand
array of strings
nothing is expandedFolders to reveal after generationA folder that does not exist is skipped
description
string
noneOne line for the bundled sample indexThe generator does not read it
Unknown keys are ignored

A key CodeBaker does not know (a typo such as placeholder instead of placeholders, or a leftover select) is ignored silently. No error, no warning. If a setting seems to do nothing, check its spelling against this table.

The file is JSON5, so it can hold comments, trailing commas and keys without quotes. See Why JSON5?.


Complete Schema​

{
// Identity (all optional, see the field details below)
id: "laravel-model",
name: "Laravel Model",
version: "1.0.0",
description: "Only shown in the bundled sample list",

// Variables: every value is a plain string. Resolved top to bottom.
vars: {
modelName: "User",
tableName: "___modelName___s", // computed from a variable above
entityKey: "[[ modelName | variable ]]", // computed with a filter, in this template's own delimiters (see syntax below)
modelNamespace: "App\\Models",
},

// Lists and objects go here. Each top-level key becomes a template variable
// and the whole block is editable in the dialog.
json: {
fields: ["name", "email", "password"],
},

// Optional: the placeholder styles used in the template files (only Pebble's {{ name }} is built in)
placeholders: ["___VAR___"],

// Optional: the Pebble delimiters of this template: "curly" (default), "square", "angle" or { print, tag, comment }
syntax: "square",

// Where the template is offered (relative to the project root)
paths: {
include: ["app/Models", "app/Models/**"],
exclude: ["**/vendor", "**/vendor/**"],
},

// Plain text replacements applied everywhere (content, file names, open, expand)
replace: {
"OldNamespace": "NewNamespace",
},

// Template files that are NOT generated (paths inside the template, globs)
ignore: ["notes/**", "notes"],

// After generation. Paths are relative to the folder you generated into.
open: ["___modelName___.php"],
expand: ["Concerns"],
}

Field Details​

Type: string

Purpose: The name shown in New → Generate from Template. It is not enforced: without a name the menu shows the template's folder name.

name: "Laravel Model"

Keep it short and descriptive. A version, if you set one, is appended in parentheses.


id (optional)​

Type: string

Purpose: A short, stable identifier used when a template is installed (see Installing Templates). It becomes the template's folder name under .CodeBaker/. id does not change how a template generates; it only names the folder when the template is installed.

id: "laravel-model"

The folder name is chosen in this order: id, then name, then the archive's file name, then the fixed name template. Whatever is chosen is cleaned up so it is safe on every operating system:

  • letters and digits (of any script) and -, _, . are kept; every other character becomes -
  • runs of - or . are collapsed to one
  • -, _ and . are trimmed from both ends (no hidden or trailing-dot folders)
  • the result is cut to 64 characters
  • Windows reserved names such as con or nul get the prefix template-

version (optional)​

Type: string (for example "1.2.0")

Purpose: The version of the template. It is shown next to the template name in the New → Generate from Template menu (as Name (v1.2.0)), in the install dialog when you update an installed template, and every generation records it in the run history.

version: "1.2.0"

Write it as a string. 1, 1.2, v1.2.3 and 1.2.3-beta.1 are understood (a leading v is not doubled); any other text is just shown as written next to the name, and is not compared when you update.


Type: object whose values are strings (booleans and numbers are accepted and turned into text)

Purpose: The variables of the template. Each one becomes a text field in the first wizard step, with the value you write as its default. Not enforced: a template without vars simply has no custom fields.

Lists and objects do not become variables

Arrays and objects written directly in vars are silently dropped: no field, no variable, no error. fields: ["id", "name"] does nothing there. Every field in the dialog is a plain text field (there are no checkboxes). Put lists and objects in the json section instead.

Rules:

  1. Text fields. Write values as strings. A boolean or a number (hasTimestamps: true, perPage: 20) works too: it becomes the text "true" or "20" in the dialog, and a number keeps the way you wrote it (1.50 stays 1.50). For anything unusual, such as 1e3, write a string.
  2. Top-to-bottom resolution. Each value is run through the template engine (Pebble) with the values resolved before it, so computed values work: tableName: "___modelName___s" or entityKey: "{{ entityName | variable }}" (filters are listed in Inflection Filters). A variable can only use variables defined above it.
  3. Built-in variables come first. The system properties are placed before your own fields. In an IDE that can work out a namespace (PhpStorm, or any IDE with the PHP plugin) an automatic NAMESPACE field comes with them, filled with the namespace of the folder you generate into. In other IDEs there is no such field: declare NAMESPACE in vars yourself if your template needs it.
  4. Names should use letters, digits and _, so that your declared placeholders (such as ___name___) can find them.

After resolution, text that is exactly true or false, or a plain number, is converted to a boolean or a number (03 or 1.50 stay text). So a field holding false switches {% if x %} off, and a field holding 20 works in comparisons such as {% if x > 10 %}.

vars: {
// Simple input
className: "Product",

// Computed from variables defined above
fileName: "___className___.php",
tableName: "___className___s",

// Computed with a filter
classKey: "{{ className | variable }}",
}

Resolution order:

{
vars: {
a: "value", // step 1
b: "___a___", // step 2: can use a
c: "___a___ ___b___", // step 3: can use a and b
d: "___e___", // e is not defined yet, so this most likely renders as empty text
e: "value", // step 5
}
}

json (optional)​

Type: object (or any JSON value, shown as text)

Purpose: Lists and objects for your template. The block is shown in an editable JSON area of the first wizard step, so users can reshape it before generating. When the JSON is an object, each of its top-level keys becomes a template variable that you can use in files, in open and in the advanced mapping file. A key with the same name as a vars entry wins.

json: {
fields: [
{ name: "title", type: "text" },
{ name: "done", type: "checkbox" },
],
}

In a template file: {% for f in fields %} ... {{ f.name }} ... {% endfor %}.

The JSON area is read as JSON5, and placeholders in it such as {{ entityName }} are filled in with your resolved vars first. If the JSON is not an object (for example an array at the top level), it is shown in the dialog but adds no variables. For a full working example, open the CRUD Demo sample template (see Getting Started).


Built-in variables​

Every template can use the system properties with no configuration: {{ DATE }} in file content, and {{ DATE }} in file names (and ___DATE___ once you declare that style under placeholders). The dialog lists them in a collapsed System Properties section, where you can also change them for a single run. The full list, with sample values, is on the System Properties page.


placeholders (optional)​

Type: array<string>

Purpose: Declare the placeholder styles your template uses (for example "___VAR___", "%VAR%" or "[[VAR]]"), for the cases where Pebble's {{ name }} does not fit the syntax of a language and your IDE would complain. A style listed here is used in file contents, in file and folder names, in the open and expand paths and in replace rules.

Nothing is built in. Without placeholders, only Pebble's own syntax works: {{ var }} in file contents (and in vars values, the JSON area and codebaker.advanced.json5), and in names and paths a bare variable or a dotted path ({{ var }}, {{var}}, {{ user.name }}; filters and expressions are not evaluated there). Any other style, including ___VAR___, works only after you list it.

How a style works: VAR stands for the variable name, which may use letters, digits and _. With the style ___VAR___:

  • In file contents ___modelName___ becomes the Pebble expression {{ modelName }}, so typed values (a boolean, a number) and _dot_ access for a nested value (___item_dot_name___ is item.name) work, and a name that is not a variable becomes empty text.
  • In file and folder names (and the other paths) ___modelName___ is replaced by the value of the variable, and _dot_ works too. A name that is not a variable is left as written.
  • All listed styles are active at the same time. There is no "first style wins".
  • A style that does not contain the text VAR is ignored.
  • Prefer styles with a closing delimiter (___VAR___, %VAR%) so one variable name cannot match the start of another.
// One style
placeholders: ["___VAR___"]

// Several styles at once
placeholders: ["___VAR___", "%VAR%", "[[VAR]]"]
Choose styles carefully

In file contents, text that matches a declared style is replaced whether or not a variable of that name exists: an unknown name turns into empty text. That is useful (the ___alt1___ suffix trick relies on it), but it means a style must not occur in your code by accident. Triple underscores are unlikely to collide with real code; avoid short styles such as _VAR_, $VAR$ or %VAR% in languages where those characters are common.

Text inside a {% raw %} block is not converted, so a raw block protects code that happens to match a declared style. See Escaping Text.

See also Core Principles. If the files you generate already use {{ }} or {% %} themselves, see syntax and how it differs from placeholders in placeholders or syntax?.


syntax (optional)​

Type: string or object. Default: "curly", which is Pebble's usual {{ }}, {% %} and {# #}.

Purpose: Choose the delimiters CodeBaker uses for Pebble in this template, for example when the files you generate already contain {{ }} or {% %} of their own (Vue, Angular, Handlebars, Twig, Blade, Jinja, Go templates).

syntax: "square", // [[ name ]] [% if x %] [# note #]

The names are curly, square and angle, or you give three pairs of your own. The sets, the rules for a custom set and the difference from placeholders are on The syntax Setting.


paths (optional)​

Type: object

Purpose: Control in which folders the template is offered in the context menu.

  • include: folders where the template is offered. Missing or empty means everywhere.
  • exclude: folders where it is hidden. Checked first.
paths: {
include: ["app/Models", "app/Models/**"],
exclude: ["**/vendor", "**/vendor/**", "**/node_modules", "**/node_modules/**"],
}

What is matched: the folder you right-click, written relative to the project root with /. The project root itself is the empty path, and so is a selected file.

Supported syntax (only these):

PatternMeaning
*Any characters except / (one folder level)
**Any characters including / (any number of levels)
**/Any folders, or none: **/vendor matches vendor and lib/vendor
.A literal dot

Anything else is not supported: ?, [abc], {a,b} and negation. Other characters are passed on unchanged and can behave unexpectedly. A pattern such as tests/{Unit,Feature}/** is not valid: that template is left out of the menu and a warning balloon says why. List each folder separately instead.

Examples, matched against the folder you right-click:

PatternMatchesDoes not match
app/Modelsapp/Modelsapp/Models/Admin
app/Models/*app/Models/Adminapp/Models, app/Models/Admin/Deep
app/Models/**app/Models/Admin, app/Models/Admin/Deepapp/Models itself
src/*/kotlinsrc/main/kotlinsrc/docs/lang/kotlin
**every folder, including the project root

Two things to remember:

  • app/Models/** does not match app/Models itself. To offer a template in a folder and everything below it, list both: ["app/Models", "app/Models/**"]. The same goes for exclude: **/vendor/** hides the folders inside a vendor folder but not vendor itself, so add **/vendor.
  • Patterns that end in a file extension, such as src/**/*.ts, can never match a folder, so the template would never be offered. Use src/**.

replace (optional)​

Type: object

Purpose: Direct text replacements. Each key is replaced by its value, as plain text (not a regular expression), before variables are applied.

Where it applies: file content, file and folder names, target paths, and the open and expand paths. In file content it does not change the text inside a raw or verbatim block, or a printed string such as {{ 'text' }}: those are set aside first and come out exactly as written. To rewrite a value inside what would otherwise be one block, end the block before it and start another one after it.

replace: {
// Namespace replacement
"OldNamespace": "NewNamespace",

// Remove special markers
"___REMOVE___": "",
}

Order for each piece of text:

  1. replace substitutions
  2. Variable placeholders (the declared placeholders)
  3. For file content: the template engine (Pebble)

A value of replace may itself contain a placeholder or an expression, such as "OldNamespace": "___ns___" or "User": "{{ modelName }}". It is filled in afterwards, which is how working code is turned into a template.

Config-level vs. in-file replacement

This replace applies unconditionally, everywhere the text appears across the whole template. To replace a value at one specific spot in a file, while keeping the real value visible and IDE-valid as you edit, use a //CodeBaker: replace comment directive in the template file. See Inline & Block Value Replacement.


ignore (optional)​

Type: array<string>

Purpose: Template files and folders that should not be generated, for example author notes or a screenshot you keep next to the template.

The patterns are matched against each path inside the template folder (forward slashes, no leading /), with the same * / ** rules as paths. A folder pattern such as notes/** matches what is inside the folder, not the folder itself, so list both:

ignore: ["notes", "notes/**", "**/*.psd"]

codebaker.config.json5, codebaker.advanced.json5 and .history are always skipped, with no need to list them.


open (optional)​

Type: array<string>

Purpose: Files to open in the editor after generation.

open: [
"___modelName___.php",
"tests/___modelName___Test.php",
]

Behavior:

  • Paths are relative to the folder you generated into, not to the project root. A path that starts with / is taken from the project root instead.
  • Variables and replace are applied to each path first, so ___name___ works in a path.
  • All listed files are opened, in order. The last one is focused and selected in the Project view.
  • A file that does not exist after generation is skipped.
  • If open is missing or empty, nothing is opened.

expand (optional)​

Type: array<string>

Purpose: Folders to reveal in the Project view after generation.

expand: ["Concerns", "tests"]

Behavior:

  • Same path rules as open: relative to the folder you generated into, a leading / means the project root.
  • Folders are expanded before the files in open are opened.
  • A folder that does not exist is skipped.

description (optional)​

Type: string

Purpose: One line about the template. The generator does not read it. It is used only by the plugin's bundled sample index (the Install Sample Templates dialog), so a template of your own does not need it.

description: "A small branded CRUD web app, one page per entity."

See also​