hokey-cokey
v2.1.0Hokey Cokey! Simple string template rendering and matching
Hokey Cokey is a quick tool for matching placeholders from, and inserting placeholders into, template strings. Useful for cases where RegExps are too fussy and you want something chunky and robust without having to worry about edge cases.
Match: Match a target string against a template and return a list of found values
e.g. places/:country/{city}
+ places/france/paris
= { country: "france", city: "paris" }
Render: Take a template string, merge in some values, and return the rendered string.
e.g. places/${country}/:city
+ { country: "france", city: "paris" }
= places/france/paris
Things to know:
- Works with named placeholders in multiple formats:
:express
,{jsx}
,{{handlebars}}
or${es6}
- Named placeholders must match the format
[a-zA-Z][a-zA-Z0-9]
- Works with
*
placeholder (matched values are zero-indexed) - Doesn't do anything complicated like RegExp patterns or optional placeholders
- Template parsing is cached for performance
- Fully unit-tested, 100% covered, all inputs are validated, throws friendly error messages
Installation
npm install hokey-cokey
Usage
match(templates: string|string[], target: string)
Matches a template string against a target string and return an object containing values corresponding to the placeholders.
templates
can be...- String containing one or more placeholders in any allowed format
- Array (or any iterable object) with multiple template strings to attempt to match
- Function that returns a template string (called with
target
) - Generator function that yields multiple template strings (called with
target
)
target
must be the string to match againsttemplates
- Returns an object in
placeholder: value
format, orfalse
if the template doesn't match
const { match } = require('hokey-cokey');
// Match named placeholders in template.
match("places/{country}/{city}", "places/france/paris"); // { country: "france", city: "paris" }
match("places/:country/:city", "places/france/paris"); // { country: "france", city: "paris" }
// Match numbered placeholders in template.
match("*-*-*", "A-B-C"); // { "0": "A", "1": "B", "2": "C }
// Match several possible templates.
const templates = [
"${dog}===${cat}",
"{name}@{domain}",
"places/:country/:city",
];
match(templates, "places/france/paris"); // { country: "france", city: "paris" }
Template must have one character between each placeholder or an error will be thrown:
match("{placeholders}{with}{no}{gap}", "abcd"); // throws SyntaxError "template: Placeholders must be separated by at least one character"
render(template: string, values: Object|Function|string)
Render a set of values into a template string.
template
must be a string containing one or more placeholders in any allowed formatvalues
can be:- Object containing string or function keys
- Function called for each placeholder (receives the placeholder name)
- String used for all placeholders
- Returns the rendered string
const { render } = require("hokey-cokey");
// Render named values into template.
render("blogs-:category-:slug", { category: "cheeses", slug: "stilton" }); // blogs-cheeses-stilton
render("blogs-:category-:slug", "Arrrrgh"); // blogs-Arrrrgh-Arrrrgh
render("blogs-:category-:slug", (p) => p.toUpperCase()); // blogs-CATEGORY-SLUG
// Render numbered values into template (using an array works!)
render("*-*-*", ["A", "B", "C"]); // A-B-C
If using an object with values the keys must correspond to placeholders in the template or render will fail:
render("{name}-{date}", { name: "Dave" }); // Throws ReferenceError "values.date: Must be defined"
render("*-*", { "0": "Dave" }); // Throws ReferenceError "values.1: Must be defined"
placeholders(template: string)
Parse a template string and return an array of found placeholders.
template
must be a string containing one or more placeholders in any allowed format- Returns an array of string placeholder names that were found in the template
const { placeholders } = require("hokey-cokey");
// Extract the placeholder names.
placeholders("{username}@{domain}"); // ["username", "domain"]
placeholders(":name // ${age}"); // ["name", "age"]
Changelog
See Releases