Skip to content

handlebars()

bingo-handlebars exports three primary functions for directly using Handlebars templates in Bingo templates:

Each function generates files Creations using Handlebars templates on disk. Each takes up to two parameters:

  1. sourcePath: string (required): absolute path to a Handlebars template file or directory
  2. options: object (optional): any values to use in the templates

handlebars

Generates files creations from a directory of templates or a single template file.

For example, this template uses a ../template/package.json.hbs file relative to the template’s source file:

import { createTemplate } from "bingo";
import { handlebars } from "bingo-handlebars";
import path from "node:path";
export default createTemplate({
about: { name: "My Handlebars Template" },
options: {
owner: z.string(),
repository: z.string(),
},
async produce({ options }) {
return {
files: {
"package.json": await handlebars(
path.join(import.meta.dirname, "../template/package.json.hbs"),
options,
),
},
};
},
});

If a template/package.json.hbs file exists with the following contents:

template/package.json.hbs
{
"name": "{{repository}}",
"repository": {
"type": "git",
"url": "https://github.com/{{owner}}/{{repository}}",
}
}

Given the options { owner: "your-username", repository : "my-handlebars-app" }, the created package.json would look like:

package.json
{
"name": "my-handlebars-app",
"repository": {
"type": "git",
"url": "https://github.com/your-username/my-handlebars-app"
}
}

handlebarsDirectory

Behaves the same as handlebars(), but only supports generating from a directory. Throws an error if the sourcePath is a file.

import { createTemplate } from "bingo";
import { handlebarsDirectory } from "bingo-handlebars";
import path from "node:path";
export default createTemplate({
about: { name: "My Handlebars Template" },
options: {
owner: z.string(),
repository: z.string(),
},
async produce({ options }) {
return {
files: await handlebarsDirectory(
path.join(import.meta.dirname, "../template"),
options,
),
};
},
});

This can be useful for locations such as the root file Creation where TypeScript requires a directory (CreatedDirectory) rather than a file (CreatedFileEntry).

handlebarsFile

Behaves the same as handlebars(), but only supports generating a single file. Throws an error if the sourcePath is a directory.

import { createTemplate } from "bingo";
import { handlebarsFile } from "bingo-handlebars";
import path from "node:path";
export default createTemplate({
about: { name: "My Handlebars Template" },
options: {
owner: z.string(),
repository: z.string(),
},
async produce({ options }) {
return {
files: {
"package.json": await handlebarsFile(
path.join(import.meta.dirname, "../template/package.json.hbs"),
options,
),
},
};
},
});

This can be useful for locations where TypeScript requires a file (CreatedFileEntry) rather than a directory (CreatedDirectory).

Directories

Directory paths given to handlebars() and handlebarsDirectory() will be recursively read. Any file names ending with .hbs will have that suffix removed.

For example, this template uses a ../template directory relative to the template’s source file for all its files Creations:

import { createTemplate } from "bingo";
import { handlebars } from "bingo-handlebars";
import path from "node:path";
export default createTemplate({
about: { name: "My Handlebars Template" },
options: {
owner: z.string(),
repository: z.string(),
},
async produce({ options }) {
return {
files: await handlebars(
path.join(import.meta.dirname, "template"),
options,
),
};
},
});

If the template/ directory contains README.md.hbs and package.json.hbs template files, then README.md and package.json files will be created.

Made with 💝 in Boston by Josh Goldberg.