object-templator

0.2.0 • Public • Published

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.git

Options

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

Readme

Keywords

Package Sidebar

Install

npm i object-templator

Weekly Downloads

1

Version

0.2.0

License

MIT

Unpacked Size

12.3 kB

Total Files

4

Last publish

Collaborators

  • kmandrup