Skip to content

Instantly share code, notes, and snippets.

@scottrippey
Last active February 13, 2019 10:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save scottrippey/d712f72066d2dc7e17a6bc74d3fa0f21 to your computer and use it in GitHub Desktop.
Save scottrippey/d712f72066d2dc7e17a6bc74d3fa0f21 to your computer and use it in GitHub Desktop.
ES6 Template Helpers
import { unindent, repeat, truthy } from "template-helpers";
function createMessage(user, notifications) {
return unindent(truthy`
Hello, ${ user.name }!
${(notifications.length > 0) && truthy`
You have ${ notifications.length } new notification${ (notifications.length > 1) && "s" }.
${repeat(notifications, notification => truthy`
* ${ notification.title } ${ notification.important && "!" }
`)}
`}
Have a nice day!
`);
}
/**
* Example output:
*/
`Hello, Scott!
You have 3 new notifications.
* Yesterday was awesome!
* Today is awesome!
* Tomorrow will be awesome!
Have a nice day!
`;
/**
* Side Note:
* I realize there's an "extra whitespace" issue in these results, which I don't like.
* I have a solution, but I didn't want to over-complicate this example with it.
*/
export { unindent, replaceAll, repeat, truthy, zipTemplate };
/**
* Removes a fixed amount of whitespace from the text block.
*
* @example
* unindent(`
* One
* Two
* Three
* `)
* === "One\n Two\nThree\n"
* @param {string} text
*/
function unindent(text) {
var firstWhitespace = text.match(/^\s*/)[0];
return replaceAll(text, firstWhitespace, "\n");
}
function replaceAll(text, search, replace) {
return text.split(search).join(replace);
}
/**
* Template helper for looping over items
*
* @example
* `
* Numbers:
* ${ repeat([1,2,3], val => `
* > ${ val }
* `)}
* `
* === "Numbers: > 1 > 2 > 3
*
* @param {*[]} items
* @param {function(value, index)} templateFn
* @param {string} [spacer]
* @return {string}
*/
function repeat(items, templateFn, spacer) {
return items.map(templateFn).join(spacer || "");
}
/**
* This function should be used as a "template string tag",
* to omit falsey values from a template string,
* allowing easier conditional statements.
*
* @example
* truthy`
* ${ condition && value }}
* `
*
* @param strings
* @param values_
*/
function truthy(strings, values_) {
var values = Array.prototype.slice.call(arguments, 1);
// Replace falsey values with empty strings:
function shouldOmit(value) {
return !value && value !== 0;
}
values = values.map(value => shouldOmit(value) ? "" : value);
return zipTemplate(strings, values);
}
function zipTemplate(strings, values) {
var results = [];
results.push(strings[0]);
for (var i = 0; i < values.length; i++) {
results.push(values[i]);
results.push(strings[i + 1]);
}
return results.join("");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment