object-templator v0.2.0
Object Templator
Object Templator is a new type of template engine specifically designed to create nested structures such as js, JSON or YAML objects without the unnatural fit of traditional text based templates.
Uses sandboxed js via run-sandboxed
Usage
Here is how it looks in action for generating part of a package.json file.
// sandboxed.sjs
ctx.template = {
opts: {
type: 'js',
indent: 4
},
base: {
// baseline object (static)
private: true,
license: 'MIT'
},
parts: {
// root level of object
$root$({name}) {
return {
name
}
},
// dynamic entries of object...
author({
author
}) {
return return author === 'unknown' ? undefined : { name: _.humanize(author) }
},
repo({
username,
name
}) {
return {
url: `github:${_.lowercase(username)}/${name}.git`
}
}
}
}Filtering out parts
You can have a part return null or undefined in order to completely filter out that part.
In the example above, in the author part, we return undefined if author is unknown in order to filter out that part entirely in that particular case.
You can pass an options keepAllParts: true to override this filtering behavior, to keep the output of all parts no matter what. We don't (yet) support partial filtering of parts. Either you opt to filter them out (default) or not.
API
const {
objTemplate
} = require('object-templator')
const filePath = path.join(__dirname, 'sandboxed.sjs')
const params = {
author: 'Kristian',
username: 'kmandrup',
name: 'my-project'
}
return objTemplate(filePath, params, {
override: true,
type: 'json'
})sandboxed.sjs is run securely as javascript in a vm2 sandbox.
powerdash functions are made available via _ so you have all the power of lodash, string.js and underscore.string that act as extensions to the lodash API.
Sending the params:
{
name: 'power-lib',
author: 'kristian mandrup',
username: 'Kmandrup'
}Will produce the following
js result
module.exports = {
name: 'power-lib',
private: true,
license: 'MIT',
author: 'Kristian Mandrup',
repo: {
url: 'github:kmandrup/power-lib.git'
}
}JSON result
{
"name": "power-lib",
"private": true,
"license": "MIT",
"author": "Kristian Mandrup",
"repo": {
"url": "github:kmandrup/power-lib.git"
}
}YAML result
---
name: power-lib
private: true
license: MIT
author: Kristian Mandrup
repo:
url: github:kmandrup/power-lib.gitOptions
You can use the mode option to split params by parts of the template, so that you can send specific params to specific parts of the object.
Use override to have your opts override those of the object template defintion, such as the indent to use on the JSON result (so as to fit your particular code formating conventions).
const params = {
$root$: {
name: 'kristian mandrup'
}
author: {
name: 'kristian mandrup',
email: 'kmandrup@gmail.com'
},
repo: {
username: 'kmandrup'
}
}
// map of custom transformation functions by type
const transform = {
xml(obj) {
return objToXml(obj)
}
}
const result = transformTree(ctx.treeDef, params, {
mode: 'split',
override: true,
transform, // pass map of custom transformation functions
indent: 4
})Advanced options
key
Set the key used to place the result in the ctx object. The default key is template
transform
Pass a custom map of transformation functions.
const transform = {
xml(obj) {
return objToXml(obj)
}
}
transformTree(ctx.template, params, {
transform
})transformObj(obj, type, options)
Pass a custom transformObj function to transform the result object.
Note that the defaults option contains the default transformObj function, which can be used as a fallback.
function transformObj(obj, type, options) {
switch (type) {
case 'swagger':
// ...
return toSwagger(obj)
// more special cases ...
default:
return options.defaults.transformObj(obj, type, options)
}
}transformTree
In some cases you might want to use the transformTree function directly, without going through loading the treeDef from a js VM sandbox.
import {
transformTree
} from 'object-templator'
transformTree(treeDef, params, opts)Alternatives
Some alternatives you could consider for simple object templating. These engines could be combined with run-sandboxed and then transformed to the final result.
var templateObj = require("template-obj");
return templateObj({
key1: "value1",
key2: "${key1} value2"
});var objTemplate = require('obj-template');
var config = {
baseURL: 'http://www.example.com',
urls: [
"<%= baseURL %>/homepage",
"<%= baseURL %>/menu",
"<%= baseURL %>/contacts"
]
};
return objTemplate(config);Runs underscore's _.template over an object structure
License
MIT