{"_id":"loom","_rev":"59-19a60eb853fb0d3cce5905a48cfdfc35","name":"loom","description":"Weave your wefts betwixt the warps of loom generators and scaffolds.","dist-tags":{"latest":"3.1.2","beta":"3.0.0-beta.3"},"versions":{"1.0.0":{"name":"loom","description":"a simple and powerful API for differential inheritance and AOP","version":"1.0.0","homepage":"https://github.com/rpflorence/loom","authors":["Ryan Florence <@ryanflorence>"],"repository":{"type":"git","url":"git://github.com/rpflorence/loom.git"},"main":"./src/loom.js","ender":"./src/ender.js","dependencies":{},"devDependencies":{},"_id":"loom@1.0.0","engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.0.5","_nodeVersion":"v0.4.6","_defaultsLoaded":true,"dist":{"shasum":"9df0c8f64036e53c120e1513e3c1b2988cd12a0d","tarball":"https://registry.npmjs.org/loom/-/loom-1.0.0.tgz","integrity":"sha512-hjIdmh/I1R2p5aqHbUxXCNfmsEGMAx07zGGPYKKakqQHvLorVsid+fqeXb0ZZrqv4GOC5nMbXLKds9t49SjdRg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIF7pDyvy3JrLXLtNGEUnyXaPbmBUg/T5VWFjo1q4djPwAiAugRihI1IzuFXHkOzwY/GUer/Z/p3APcDTja0yBHi5IA=="}]},"scripts":{},"directories":{}},"2.0.0-beta.1":{"name":"loom","version":"2.0.0-beta.1","description":"Weave your wefts betwixt the warps of loom generators and scaffolds.","main":"loom.js","scripts":{"test":"node_modules/.bin/mocha --require should --reporter dot --ui bdd $(find test -name \"*.spec.js\")"},"bin":{"generate":"./bin/generate"},"author":{"name":"Ryan Florence"},"license":"MIT","dependencies":{"commander":"~2.0.0","fs-extra":"~0.6.3","loom-engine-hbs":"2.0.0","cli-color":"~0.2.2","cli-prompt":"~0.3.2"},"devDependencies":{"mocha":"~1.12.0","sinon":"~1.7.3","should":"~1.2.2"},"repository":{"type":"git","url":"git://github.com/rpflorence/loom"},"keywords":["generator","scaffold","template","templating"],"readme":"Loom\n====\n\nWeave your wefts betwixt the warps of loom generators and scaffolds.\n\n![wefts and warps](http://ryanflorence.com/gifs/warp-weft.gif)\n\n**Loom makes it easy to share best-practices and common patterns for app\ndevelopment.**\n\n- build a set of generators for public consumption based on some\n  framework or library (like ember, angular, backbone, etc.)\n- consume those sets of generators\n- override those generators\n- build your own generators for your specific app\n\nUsing Loom Generator Packages from NPM\n--------------------------------------\n\nUsing generator packages from npm is easy:\n\n```sh\nnpm install loom-generators-ember --save\ngenerate model user name:string age:number\n```\n\nThen refer to the documentation for the generators you've installed.\n\nYou must install with `--save` or add the module to your package.json\ninstead (that's how loom knows how to use them).\n\nCreating Your Own Generators\n----------------------------\n\nAlso, see [the full generator API below](#generator-api)\n\nWhile using generators others have created for you is great, its awesome\nto have a simple way to make generators for our own apps. Even if you're\nusing a set of generators from npm, defining your own generators will\noverride them.\n\n### Installation\n\n```sh\nnpm install loom -g\ngenerate --init\n```\n\n### Templates\n\nInitializing loom simply creates some directories in your project. After\nthat, all you need is a template in `./loom/templates/`:\n\nLets say we have a lot of \"meal\" objects in our app, lets make a\ntemplate for what one of these objects looks like:\n\n_loom/templates/app/meal.js.hbs_\n\n```mustache\nfunction {{objectName}}() {\n  this.food = '{{params.food}}';\n  this.venue = '{{params.venue}}';\n}\n```\n\nAnd then you can generate files based on the template:\n\n```sh\ngenerate app/meal.js lunch food:taco venue:cart\n```\n\nThis will create a file at `app/lunch.js` that looks like:\n\n```js\nfunction lunch() {\n  this.food = 'taco';\n  this.venue = 'cart';\n}\n```\n\nLoom, by default, will save files to your app in the same relative\nlocation they were found in your templates directory.\n\n### Generators\n\nWe can define a generator to make everything a little nicer. First we'll\ncreate a `present` method that determines what data goes to the\ntemplate. Then we'll tell it where to find the template so we can\nsimplify the generator command.\n\n_loom/generators/meal.js_\n\n```js\nexports.present = function(name, params) {\n  params.constructorName = name.charAt(0).toUpperCase() + name.slice(1);\n  return params;\n};\n\nexports.template = 'app/meal.js.hbs';\n```\n\nNow our template is simpler, no more `{{params.food}}` and it\ncapitalizes our constructor like a propery lady or gent.\n\n_loom/templates/meal.js.hbs_\n\n```mustache\nfunction {{constructorName}}() {\n  this.food = '{{food}}';\n  this.venue = '{{venue}}';\n}\n```\n\nAnd finally our command is simpler, it now just matches a generator\nnamed `meal` instead of a template found at `app/meal.js`.\n\n`generate meal lunch food:taco venue:cart`\n\n### Engines\n\nThe default generator uses handlebars, but we can swap it out for ejs by\ncreating a very simple \"engine\":\n\n_loom/engines/ejs.js_\n\n```js\nvar _ = require('underscore');\n// module.exports = _.template\n// that works, but for clarity:\n\nmodule.exports = function(src, locals) {\n  return _.template(src, locals);\n};\n```\n\nRename your template to `meal.js.ejs` and edit it:\n\n```ejs\nfunction <%= constructorName %>() {\n  this.food = '<%= food %>';\n  this.venue = '<%= venue %>';\n}\n```\n\nUpdate your generator to point to the proper template:\n\n```js\nexports.template = 'app/meal.js.ejs';\n```\n\nLoom looks at the file extension of the template (in this case `ejs`)\nand then tries to find a template engine named `ejs.js`.\n\nNow generate your newly configured template:\n\n`generate meal lunch food:taco venue:cart`\n\n### Multiple templates for one generator\n\nIts very common for a generator to create several files, like unit tests\nand scaffoling. Lets add a unit test template to our meal generator.\n\n_loom/templates/test/unit/meal.spec.js.ejs_\n\n```ejs\ndescribe('<%= constructorName %>', function() {\n  it('sets food to \"<%= food %>\"', function() {\n    var meal = new <%= constructorName %>();\n    expect(meal.food).to.equal('<%= food %>');\n  });\n});\n```\n\nAnd add the template path to your generator, note the rename from\n`exports.template` to `export.templates`.\n\n```js\nexports.templates = [\n  'app/meal.js.ejs',\n  'test/unit/meal.spec.js.ejs'\n];\n```\n\nBoth templates will get the same data from `generator.present` and the\nfiles will be saved to the same relative path in your app as they are\ndefined in your templates directory.\n\n### Default Generators\n\nIf you define `loom/generators/default.js`, loom will use it when a\nspecific generator is not found.\n\nPublishing Generators to NPM for Everybody\n------------------------------------------\n\nName your module `loom-generators-<name>` (like\n`loom-generators-ember`), place generators, templates, and engines in\n`./loom`, and then publish.  That's it. People can simply `npm install\nloom-generators-<name> --save` and start using them.\n\nPublishing Template Engines to NPM for Everybody\n------------------------------------------------\n\nTo add support for your favorite templating engine you can either add a\nfile to `loom/engines` or publish a module to npm named\n`loom-engine-<ext>`. Loom will attempt to require the engine if it\ndoesn't find it in your project.\n\nGenerator API\n-------------\n\nLoom has a generic generator that can be overridden to meet your specific\nuse case. Generators can export a few methods that loom will use.\n\nYour generator can implement as many methods as you need, loom will\nmerge in the `generic_generator` methods that you don't provide.\n\nHere's a generator that does nothing:\n\n_loom/generators/noop.js_\n\n```js\nexports.before = function(){};\nexports.present = function(){};\nexports.savePath = function(){};\nexports.write = function(){};\nexports.render = function(){};\nexports.template = '';\n// exports.template = function(){};\n// exports.templates = [];\n// exports.templates = function(){};\n```\n\nBelow is documentation on generator API, also, check out the [generic\ngenerator](lib/generic_generator).\n\n### generator.before\n\nExecutes before anything else happens. Useful if you need to set or\nchange some things on `env` before it moves through the other methods of\nyour generator.\n\n#### signature\n\n`function(env)`\n\n#### arguments\n\n1. env (Object) - the loom environment object.\n\n\n### generator.present\n\n#### signature\n\n`function([argN] [, params], env)`\n\n#### arguments\n\n1. argN (String) - the space separated values used in the loom command\n2. params (Object) - the key:value pairs used in the loom command\n3. env (Object) - the loom environment object\n\n#### examples\n\nLets make a generator that logs the arguments to explore how this works.\n\n_loom/generators/user.js_\n\n```js\nexports.present = function() {\n  console.log(arguments);\n};\n```\n\nThe following are commands followed by what is logged for the arguments:\n\n```sh\ngenerate model user name:string age:number\n{ '0': 'user', '2': { name: 'string', age: 'number' } }\n\ngenerate model foo bar baz qux:1 quux:2\n{ '0': 'foo',\n  '1': 'bar',\n  '2': 'baz',\n  '3': { qux: '1', quux: '2' } }\n```\n\nAs you can see, the space separated values become the arguments and the\nkey=value pairs are wrapped up into an object for the final `params` argument.\n\n\n### generator.template\n\nDetermines which template to render.\n\n`exports.template` can simply be a string, or a function if you need to\ncompute it.\n\nPaths are relative to the `./loom/templates` directory.\n\n#### example\n\nTo use a template found at\n`loom/templates/spec/models/model.spec.js.hbs`:\n\n```js\nexports.template = 'spec/models/model.spec.js.hbs';\nexports.template = function() {\n  // some computation\n  return 'spec/models/model.spec.js.hbs';\n};\n```\n\n#### notes\n\nUnless you override `generator.write` the generated file will be saved\nin the mirrored location in `loom/templates`, so the example above will\nbe saved to `spec/models/<name>.spec.js`.\n\n### generator.templates\n\nSame as `template` but is an array of template paths that take\nprecendence over `template`. Each template will receive the same locals\nreturned from `present`. Can also be a function that returns an array.\n\n#### examples\n\n```js\nexports.templates = [\n  'app/models/model.js.ejs',\n  'spec/models/model.spec.js.ejs'\n];\n\nexports.templates = function() {\n  return [\n    'app/models/model.js.ejs',\n    'spec/models/model.spec.js.ejs'\n  ];\n};\n```\n\n### generator.savePath\n\nDetermines the path in which to save a template.\n\n#### signature\n\n`function(template, env)`\n\n#### arguments\n\n1. template (String) - the path of the template being rendered\n2. env (Object) - the loom environment object\n\n### generator.write\n\nWrites a rendered template to the file system, its unlikely you'll want\nto override this.\n\n#### signature\n\n`function(templateName, src, env)`\n\n### generator.render\n\nDetermines how to render the template, its unlinkely you'll want to\noverride this.\n\n#### signature\n\n`function(engine, templatePath, locals)`\n\nTODO\n====\n\n- --force option to overwrite files (better for scripting so you don't\n  get the prompt)\n- async compatibility, right now all generator operations must be\n  sync\n\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/rpflorence/loom/issues"},"homepage":"https://github.com/rpflorence/loom","_id":"loom@2.0.0-beta.1","dist":{"shasum":"b02e56f39553faee975d2fbe21b6447163545749","tarball":"https://registry.npmjs.org/loom/-/loom-2.0.0-beta.1.tgz","integrity":"sha512-iqk+uIRhO7MfF11Mf8hVYvk5eFA2ybXBvW5FpKqucoYv3o7Why7fUTsgcziY/DwzRePzgbuVp93m6QlP/f4MrA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDZLZ2IRlOZHDLbg22Kt/9vOZJbzgbJ3DoJiUi9SaZkMAIhAIgaI6a93ERV3BGF3CBPJvsDyWo91xH2T6skOfVu2Dgi"}]},"_from":".","_npmVersion":"1.3.14","_npmUser":{"name":"ryanflorence","email":"rpflorence@gmail.com"},"maintainers":[{"name":"ryanflorence","email":"rpflorence+npm@gmail.com"}],"directories":{}},"2.0.0":{"name":"loom","version":"2.0.0","description":"Weave your wefts betwixt the warps of loom generators and scaffolds.","main":"loom.js","scripts":{"test":"node_modules/.bin/mocha --require should --reporter dot --ui bdd $(find test -name \"*.spec.js\")"},"bin":{"generate":"./bin/generate"},"author":{"name":"Ryan Florence"},"license":"MIT","dependencies":{"commander":"~2.0.0","fs-extra":"~0.6.3","sync-prompt":"~0.1.0","loom-engine-hbs":"1.0.0","cli-color":"~0.2.2"},"devDependencies":{"mocha":"~1.12.0","sinon":"~1.7.3","should":"~1.2.2"},"repository":{"type":"git","url":"git://github.com/rpflorence/loom"},"keywords":["generator","scaffold","template","templating"],"readme":"Loom\n====\n\nWeave your wefts betwixt the warps of loom generators and scaffolds.\n\n![wefts and warps](http://ryanflorence.com/gifs/warp-weft.gif)\n\n**Loom makes it easy to share best-practices and common patterns for app\ndevelopment.**\n\n- build a set of generators for public consumption based on some\n  framework or library (like ember, angular, backbone, etc.)\n- consume those sets of generators\n- override those generators\n- build your own generators for your specific app\n\nUsing Loom Generator Packages from NPM\n--------------------------------------\n\nUsing generator packages from npm is easy:\n\n```sh\nnpm install loom-generators-ember --save\ngenerate model user name:string age:number\n```\n\nThen refer to the documentation for the generators you've installed.\n\nYou must install with `--save` or add the module to your package.json\ninstead (that's how loom knows how to use them).\n\nCreating Your Own Generators\n----------------------------\n\nAlso, see [the full generator API below](#generator-api)\n\nWhile using generators others have created for you is great, its awesome\nto have a simple way to make generators for our own apps. Even if you're\nusing a set of generators from npm, defining your own generators will\noverride them.\n\n### Installation\n\n```sh\nnpm install loom -g\ngenerate --init\n```\n\n### Templates\n\nInitializing loom simply creates some directories in your project. After\nthat, all you need is a template in `./loom/templates/`:\n\nLets say we have a lot of \"meal\" objects in our app, lets make a\ntemplate for what one of these objects looks like:\n\n_loom/templates/app/meal.js.hbs_\n\n```mustache\nfunction {{objectName}}() {\n  this.food = '{{params.food}}';\n  this.venue = '{{params.venue}}';\n}\n```\n\nAnd then you can generate files based on the template:\n\n```sh\ngenerate app/meal.js lunch food:taco venue:cart\n```\n\nThis will create a file at `app/lunch.js` that looks like:\n\n```js\nfunction lunch() {\n  this.food = 'taco';\n  this.venue = 'cart';\n}\n```\n\nLoom, by default, will save files to your app in the same relative\nlocation they were found in your templates directory.\n\n### Generators\n\nWe can define a generator to make everything a little nicer. First we'll\ncreate a `present` method that determines what data goes to the\ntemplate. Then we'll tell it where to find the template so we can\nsimplify the generator command.\n\n_loom/generators/meal.js_\n\n```js\nexports.present = function(name, params) {\n  params.constructorName = name.charAt(0).toUpperCase() + name.slice(1);\n  return params;\n};\n\nexports.template = 'app/meal.js.hbs';\n```\n\nNow our template is simpler, no more `{{params.food}}` and it\ncapitalizes our constructor like a propery lady or gent.\n\n_loom/templates/meal.js.hbs_\n\n```mustache\nfunction {{constructorName}}() {\n  this.food = '{{food}}';\n  this.venue = '{{venue}}';\n}\n```\n\nAnd finally our command is simpler, it now just matches a generator\nnamed `meal` instead of a template found at `app/meal.js`.\n\n`generate meal lunch food:taco venue:cart`\n\n### Engines\n\nThe default generator uses handlebars, but we can swap it out for ejs by\ncreating a very simple \"engine\":\n\n_loom/engines/ejs.js_\n\n```js\nvar _ = require('underscore');\n// module.exports = _.template\n// that works, but for clarity:\n\nmodule.exports = function(src, locals) {\n  return _.template(src, locals);\n};\n```\n\nRename your template to `meal.js.ejs` and edit it:\n\n```ejs\nfunction <%= constructorName %>() {\n  this.food = '<%= food %>';\n  this.venue = '<%= venue %>';\n}\n```\n\nUpdate your generator to point to the proper template:\n\n```js\nexports.template = 'app/meal.js.ejs';\n```\n\nLoom looks at the file extension of the template (in this case `ejs`)\nand then tries to find a template engine named `ejs.js`.\n\nNow generate your newly configured template:\n\n`generate meal lunch food:taco venue:cart`\n\n### Multiple templates for one generator\n\nIts very common for a generator to create several files, like unit tests\nand scaffoling. Lets add a unit test template to our meal generator.\n\n_loom/templates/test/unit/meal.spec.js.ejs_\n\n```ejs\ndescribe('<%= constructorName %>', function() {\n  it('sets food to \"<%= food %>\"', function() {\n    var meal = new <%= constructorName %>();\n    expect(meal.food).to.equal('<%= food %>');\n  });\n});\n```\n\nAnd add the template path to your generator, note the rename from\n`exports.template` to `export.templates`.\n\n```js\nexports.templates = [\n  'app/meal.js.ejs',\n  'test/unit/meal.spec.js.ejs'\n];\n```\n\nBoth templates will get the same data from `generator.present` and the\nfiles will be saved to the same relative path in your app as they are\ndefined in your templates directory.\n\n### Default Generators\n\nIf you define `loom/generators/default.js`, loom will use it when a\nspecific generator is not found.\n\nPublishing Generators to NPM for Everybody\n------------------------------------------\n\nName your module `loom-generators-<name>` (like\n`loom-generators-ember`), place generators, templates, and engines in\n`./loom`, and then publish.  That's it. People can simply `npm install\nloom-generators-<name> --save` and start using them.\n\nPublishing Template Engines to NPM for Everybody\n------------------------------------------------\n\nTo add support for your favorite templating engine you can either add a\nfile to `loom/engines` or publish a module to npm named\n`loom-engine-<ext>`. Loom will attempt to require the engine if it\ndoesn't find it in your project.\n\nGenerator API\n-------------\n\nLoom has a generic generator that can be overridden to meet your specific\nuse case. Generators can export a few methods that loom will use.\n\nYour generator can implement as many methods as you need, loom will\nmerge in the `generic_generator` methods that you don't provide.\n\nHere's a generator that does nothing:\n\n_loom/generators/noop.js_\n\n```js\nexports.before = function(){};\nexports.present = function(){};\nexports.savePath = function(){};\nexports.write = function(){};\nexports.render = function(){};\nexports.template = '';\n// exports.template = function(){};\n// exports.templates = [];\n// exports.templates = function(){};\n```\n\nBelow is documentation on generator API, also, check out the [generic\ngenerator](lib/generic_generator).\n\n### generator.before\n\nExecutes before anything else happens. Useful if you need to set or\nchange some things on `env` before it moves through the other methods of\nyour generator.\n\n#### signature\n\n`function(env)`\n\n#### arguments\n\n1. env (Object) - the loom environment object.\n\n\n### generator.present\n\n#### signature\n\n`function([argN] [, params], env)`\n\n#### arguments\n\n1. argN (String) - the space separated values used in the loom command\n2. params (Object) - the key:value pairs used in the loom command\n3. env (Object) - the loom environment object\n\n#### examples\n\nLets make a generator that logs the arguments to explore how this works.\n\n_loom/generators/user.js_\n\n```js\nexports.present = function() {\n  console.log(arguments);\n};\n```\n\nThe following are commands followed by what is logged for the arguments:\n\n```sh\ngenerate model user name:string age:number\n{ '0': 'user', '2': { name: 'string', age: 'number' } }\n\ngenerate model foo bar baz qux:1 quux:2\n{ '0': 'foo',\n  '1': 'bar',\n  '2': 'baz',\n  '3': { qux: '1', quux: '2' } }\n```\n\nAs you can see, the space separated values become the arguments and the\nkey=value pairs are wrapped up into an object for the final `params` argument.\n\n\n### generator.template\n\nDetermines which template to render.\n\n`exports.template` can simply be a string, or a function if you need to\ncompute it.\n\nPaths are relative to the `./loom/templates` directory.\n\n#### example\n\nTo use a template found at\n`loom/templates/spec/models/model.spec.js.hbs`:\n\n```js\nexports.template = 'spec/models/model.spec.js.hbs';\nexports.template = function() {\n  // some computation\n  return 'spec/models/model.spec.js.hbs';\n};\n```\n\n#### notes\n\nUnless you override `generator.write` the generated file will be saved\nin the mirrored location in `loom/templates`, so the example above will\nbe saved to `spec/models/<name>.spec.js`.\n\n### generator.templates\n\nSame as `template` but is an array of template paths that take\nprecendence over `template`. Each template will receive the same locals\nreturned from `present`. Can also be a function that returns an array.\n\n#### examples\n\n```js\nexports.templates = [\n  'app/models/model.js.ejs',\n  'spec/models/model.spec.js.ejs'\n];\n\nexports.templates = function() {\n  return [\n    'app/models/model.js.ejs',\n    'spec/models/model.spec.js.ejs'\n  ];\n};\n```\n\n### generator.savePath\n\nDetermines the path in which to save a template.\n\n#### signature\n\n`function(template, env)`\n\n#### arguments\n\n1. template (String) - the path of the template being rendered\n2. env (Object) - the loom environment object\n\n### generator.write\n\nWrites a rendered template to the file system, its unlikely you'll want\nto override this.\n\n#### signature\n\n`function(templateName, src, env)`\n\n### generator.render\n\nDetermines how to render the template, its unlinkely you'll want to\noverride this.\n\n#### signature\n\n`function(engine, templatePath, locals)`\n\nTODO\n====\n\n- --force option to overwrite files (better for scripting so you don't\n  get the prompt)\n- async compatibility, right now all generator operations must be\n  sync\n\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/rpflorence/loom/issues"},"homepage":"https://github.com/rpflorence/loom","_id":"loom@2.0.0","dist":{"shasum":"3405c6ad3371a5da72639a5d345af3b1c0c6563a","tarball":"https://registry.npmjs.org/loom/-/loom-2.0.0.tgz","integrity":"sha512-J3Pmct8pTfHa8EBVVWDcUWeciWzBV4hptxSaX1ZbIO/I6TBZQ1dJGtrsJRjZ56esZ7nx+TyI4dCO9xuJ5Sbtgg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCID/DtezhJ9W0Kl/t/p00Xa8GI8dDIRWb2YSeUonZQi8kAiEA2luBF6BzXVCPEGG/uBfJGspHMpZzW6O9sbqm9IyHq10="}]},"_from":".","_npmVersion":"1.3.14","_npmUser":{"name":"ryanflorence","email":"rpflorence@gmail.com"},"maintainers":[{"name":"ryanflorence","email":"rpflorence+npm@gmail.com"}],"directories":{}},"3.0.0-beta.1":{"name":"loom","version":"3.0.0-beta.1","description":"Weave your wefts betwixt the warps of loom generators and scaffolds.","main":"loom.js","scripts":{"test":"node_modules/.bin/mocha --require should --reporter dot --ui bdd $(find test -name \"*.spec.js\")"},"bin":{"generate":"./bin/generate"},"author":{"name":"Ryan Florence"},"license":"MIT","dependencies":{"commander":"~2.0.0","fs-extra":"~0.6.3","loom-engine-hbs":"2.0.0","cli-color":"~0.2.2","cli-prompt":"~0.3.2"},"devDependencies":{"mocha":"~1.12.0","sinon":"~1.7.3","should":"~1.2.2"},"repository":{"type":"git","url":"git://github.com/rpflorence/loom"},"keywords":["generator","scaffold","template","templating"],"readme":"Loom\n====\n\nWeave your wefts betwixt the warps of loom generators and scaffolds.\n\n![wefts and warps](http://ryanflorence.com/gifs/warp-weft.gif)\n\n**Loom makes it easy to share best-practices and common patterns for app\ndevelopment.**\n\n- build a set of generators for public consumption based on some\n  framework or library (like ember, angular, backbone, etc.)\n- consume those sets of generators\n- override those generators\n- build your own generators for your specific app\n\nUsing Loom Generator Packages from NPM\n--------------------------------------\n\nUsing generator packages from npm is easy:\n\n```sh\nnpm install loom-generators-ember --save\ngenerate model user name:string age:number\n```\n\nThen refer to the documentation for the generators you've installed.\n\nYou must install with `--save` or add the module to your package.json\ninstead (that's how loom knows how to use them).\n\nCreating Your Own Generators\n----------------------------\n\nAlso, see [the full generator API below](#generator-api)\n\nWhile using generators others have created for you is great, its awesome\nto have a simple way to make generators for our own apps. Even if you're\nusing a set of generators from npm, defining your own generators will\noverride them.\n\n### Installation\n\n```sh\nnpm install loom -g\ngenerate --init\n```\n\n### Templates\n\nInitializing loom simply creates some directories in your project. After\nthat, all you need is a template in `./loom/templates/`:\n\nLets say we have a lot of \"meal\" objects in our app, lets make a\ntemplate for what one of these objects looks like:\n\n_loom/templates/app/meal.js.hbs_\n\n```mustache\nfunction {{objectName}}() {\n  this.food = '{{params.food}}';\n  this.venue = '{{params.venue}}';\n}\n```\n\nAnd then you can generate files based on the template:\n\n```sh\ngenerate app/meal.js lunch food:taco venue:cart\n```\n\nThis will create a file at `app/lunch.js` that looks like:\n\n```js\nfunction lunch() {\n  this.food = 'taco';\n  this.venue = 'cart';\n}\n```\n\nLoom, by default, will save files to your app in the same relative\nlocation they were found in your templates directory.\n\n### Generators\n\nWe can define a generator to make everything a little nicer. First we'll\ncreate a `present` method that determines what data goes to the\ntemplate. Then we'll tell it where to find the template so we can\nsimplify the generator command.\n\n_loom/generators/meal.js_\n\n```js\nexports.present = function(name, params) {\n  params.constructorName = name.charAt(0).toUpperCase() + name.slice(1);\n  return params;\n};\n\nexports.template = 'app/meal.js.hbs';\n```\n\nNow our template is simpler, no more `{{params.food}}` and it\ncapitalizes our constructor like a propery lady or gent.\n\n_loom/templates/meal.js.hbs_\n\n```mustache\nfunction {{constructorName}}() {\n  this.food = '{{food}}';\n  this.venue = '{{venue}}';\n}\n```\n\nAnd finally our command is simpler, it now just matches a generator\nnamed `meal` instead of a template found at `app/meal.js`.\n\n`generate meal lunch food:taco venue:cart`\n\n### Engines\n\nThe default generator uses handlebars, but we can swap it out for ejs by\ncreating a very simple \"engine\":\n\n_loom/engines/ejs.js_\n\n```js\nvar _ = require('underscore');\n// module.exports = _.template\n// that works, but for clarity:\n\nmodule.exports = function(src, locals) {\n  return _.template(src, locals);\n};\n```\n\nRename your template to `meal.js.ejs` and edit it:\n\n```ejs\nfunction <%= constructorName %>() {\n  this.food = '<%= food %>';\n  this.venue = '<%= venue %>';\n}\n```\n\nUpdate your generator to point to the proper template:\n\n```js\nexports.template = 'app/meal.js.ejs';\n```\n\nLoom looks at the file extension of the template (in this case `ejs`)\nand then tries to find a template engine named `ejs.js`.\n\nNow generate your newly configured template:\n\n`generate meal lunch food:taco venue:cart`\n\n### Multiple templates for one generator\n\nIts very common for a generator to create several files, like unit tests\nand scaffoling. Lets add a unit test template to our meal generator.\n\n_loom/templates/test/unit/meal.spec.js.ejs_\n\n```ejs\ndescribe('<%= constructorName %>', function() {\n  it('sets food to \"<%= food %>\"', function() {\n    var meal = new <%= constructorName %>();\n    expect(meal.food).to.equal('<%= food %>');\n  });\n});\n```\n\nAnd add the template path to your generator, note the rename from\n`exports.template` to `export.templates`.\n\n```js\nexports.templates = [\n  'app/meal.js.ejs',\n  'test/unit/meal.spec.js.ejs'\n];\n```\n\nBoth templates will get the same data from `generator.present` and the\nfiles will be saved to the same relative path in your app as they are\ndefined in your templates directory.\n\n### Default Generators\n\nIf you define `loom/generators/default.js`, loom will use it when a\nspecific generator is not found.\n\nPublishing Generators to NPM for Everybody\n------------------------------------------\n\nName your module `loom-generators-<name>` (like\n`loom-generators-ember`), place generators, templates, and engines in\n`./loom`, and then publish.  That's it. People can simply `npm install\nloom-generators-<name> --save` and start using them.\n\nPublishing Template Engines to NPM for Everybody\n------------------------------------------------\n\nTo add support for your favorite templating engine you can either add a\nfile to `loom/engines` or publish a module to npm named\n`loom-engine-<ext>`. Loom will attempt to require the engine if it\ndoesn't find it in your project.\n\nGenerator API\n-------------\n\nLoom has a generic generator that can be overridden to meet your specific\nuse case. Generators can export a few methods that loom will use.\n\nYour generator can implement as many methods as you need, loom will\nmerge in the `generic_generator` methods that you don't provide.\n\nHere's a generator that does nothing:\n\n_loom/generators/noop.js_\n\n```js\nexports.before = function(){};\nexports.present = function(){};\nexports.savePath = function(){};\nexports.write = function(){};\nexports.render = function(){};\nexports.template = '';\n// exports.template = function(){};\n// exports.templates = [];\n// exports.templates = function(){};\n```\n\nBelow is documentation on generator API, also, check out the [generic\ngenerator](lib/generic_generator).\n\n### generator.before\n\nExecutes before anything else happens. Useful if you need to set or\nchange some things on `env` before it moves through the other methods of\nyour generator.\n\n#### signature\n\n`function(env)`\n\n#### arguments\n\n1. env (Object) - the loom environment object.\n\n\n### generator.present\n\n#### signature\n\n`function([argN] [, params], env)`\n\n#### arguments\n\n1. argN (String) - the space separated values used in the loom command\n2. params (Object) - the key:value pairs used in the loom command\n3. env (Object) - the loom environment object\n\n#### examples\n\nLets make a generator that logs the arguments to explore how this works.\n\n_loom/generators/user.js_\n\n```js\nexports.present = function() {\n  console.log(arguments);\n};\n```\n\nThe following are commands followed by what is logged for the arguments:\n\n```sh\ngenerate model user name:string age:number\n{ '0': 'user', '2': { name: 'string', age: 'number' } }\n\ngenerate model foo bar baz qux:1 quux:2\n{ '0': 'foo',\n  '1': 'bar',\n  '2': 'baz',\n  '3': { qux: '1', quux: '2' } }\n```\n\nAs you can see, the space separated values become the arguments and the\nkey=value pairs are wrapped up into an object for the final `params` argument.\n\n\n### generator.template\n\nDetermines which template to render.\n\n`exports.template` can simply be a string, or a function if you need to\ncompute it.\n\nPaths are relative to the `./loom/templates` directory.\n\n#### example\n\nTo use a template found at\n`loom/templates/spec/models/model.spec.js.hbs`:\n\n```js\nexports.template = 'spec/models/model.spec.js.hbs';\nexports.template = function() {\n  // some computation\n  return 'spec/models/model.spec.js.hbs';\n};\n```\n\n#### notes\n\nUnless you override `generator.write` the generated file will be saved\nin the mirrored location in `loom/templates`, so the example above will\nbe saved to `spec/models/<name>.spec.js`.\n\n### generator.templates\n\nSame as `template` but is an array of template paths that take\nprecendence over `template`. Each template will receive the same locals\nreturned from `present`. Can also be a function that returns an array.\n\n#### examples\n\n```js\nexports.templates = [\n  'app/models/model.js.ejs',\n  'spec/models/model.spec.js.ejs'\n];\n\nexports.templates = function() {\n  return [\n    'app/models/model.js.ejs',\n    'spec/models/model.spec.js.ejs'\n  ];\n};\n```\n\n### generator.savePath\n\nDetermines the path in which to save a template.\n\n#### signature\n\n`function(template, env)`\n\n#### arguments\n\n1. template (String) - the path of the template being rendered\n2. env (Object) - the loom environment object\n\n### generator.write\n\nWrites a rendered template to the file system, its unlikely you'll want\nto override this.\n\n#### signature\n\n`function(templateName, src, env)`\n\n### generator.render\n\nDetermines how to render the template, its unlinkely you'll want to\noverride this.\n\n#### signature\n\n`function(engine, templatePath, locals)`\n\nTODO\n====\n\n- --force option to overwrite files (better for scripting so you don't\n  get the prompt)\n- async compatibility, right now all generator operations must be\n  sync\n\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/rpflorence/loom/issues"},"homepage":"https://github.com/rpflorence/loom","_id":"loom@3.0.0-beta.1","dist":{"shasum":"ea6f4962b763d0d8d472a4dc9b114cb7a12684be","tarball":"https://registry.npmjs.org/loom/-/loom-3.0.0-beta.1.tgz","integrity":"sha512-4YFwQ6R6dTkV9ok6fAXoQsLqZQxJCXAqaeopMRh67eedwvt5o/dUlNTG0B6RBQbAGNMFEyXSf8ryApFAJV+FhQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEzdWsWORSn1h1DEpQmVDmifRbMg1Uu9HHlDLmUXogFHAiEA8ATto1tAPMlbVpdE0DHd9MoIL0xT3OkmiUcLQg6iQrg="}]},"_from":".","_npmVersion":"1.3.14","_npmUser":{"name":"ryanflorence","email":"rpflorence@gmail.com"},"maintainers":[{"name":"ryanflorence","email":"rpflorence+npm@gmail.com"}]},"3.0.0-beta.2":{"name":"loom","version":"3.0.0-beta.2","description":"Weave your wefts betwixt the warps of loom generators and scaffolds.","main":"loom.js","scripts":{"test":"node_modules/.bin/mocha --require should --reporter dot --ui bdd $(find test -name \"*.spec.js\")","watch":"node_modules/.bin/mocha --watch --require should --reporter dot --ui bdd $(find test -name \"*.spec.js\")"},"bin":{"generate":"./bin/generate"},"author":{"name":"Ryan Florence"},"license":"MIT","dependencies":{"commander":"~2.0.0","fs-extra":"~0.6.3","loom-engine-hbs":"2.0.0","cli-color":"~0.2.2","cli-prompt":"~0.3.2"},"devDependencies":{"mocha":"~1.12.0","sinon":"~1.7.3","should":"~1.2.2"},"repository":{"type":"git","url":"git://github.com/rpflorence/loom"},"keywords":["generator","scaffold","template","templating"],"readme":"Loom\n====\n\nWeave your wefts betwixt the warps of loom generators and scaffolds.\n\n![wefts and warps](http://ryanflorence.com/gifs/warp-weft.gif)\n\n**Loom makes it easy to share best-practices and common patterns for app\ndevelopment.**\n\n- build a set of generators for public consumption based on some\n  framework or library (like ember, angular, backbone, etc.)\n- consume those sets of generators\n- override those generators\n- build your own generators for your specific app\n\nUsing Loom Generator Packages from NPM\n--------------------------------------\n\nUsing generator packages from npm is easy:\n\n```sh\nnpm install loom-generators-ember --save\ngenerate model user name:string age:number\n```\n\nThen refer to the documentation for the generators you've installed.\n\nYou must install with `--save` or add the module to your package.json\ninstead (that's how loom knows how to use them).\n\nCreating Your Own Generators\n----------------------------\n\nAlso, see [the full generator API below](#generator-api)\n\nWhile using generators others have created for you is great, its awesome\nto have a simple way to make generators for our own apps. Even if you're\nusing a set of generators from npm, defining your own generators will\noverride them.\n\n### Installation\n\n```sh\nnpm install loom -g\ngenerate --init\n```\n\n### Templates\n\nInitializing loom simply creates some directories in your project. After\nthat, all you need is a template in `./loom/templates/`:\n\nLets say we have a lot of \"meal\" objects in our app, lets make a\ntemplate for what one of these objects looks like:\n\n_loom/templates/app/meal.js.hbs_\n\n```mustache\nfunction {{objectName}}() {\n  this.food = '{{params.food}}';\n  this.venue = '{{params.venue}}';\n}\n```\n\nAnd then you can generate files based on the template:\n\n```sh\ngenerate app/meal.js lunch food:taco venue:cart\n```\n\nThis will create a file at `app/lunch.js` that looks like:\n\n```js\nfunction lunch() {\n  this.food = 'taco';\n  this.venue = 'cart';\n}\n```\n\nLoom, by default, will save files to your app in the same relative\nlocation they were found in your templates directory.\n\n### Generators\n\nWe can define a generator to make everything a little nicer. First we'll\ncreate a `present` method that determines what data goes to the\ntemplate. Then we'll tell it where to find the template so we can\nsimplify the generator command.\n\n_loom/generators/meal.js_\n\n```js\nexports.present = function(name, params) {\n  params.constructorName = name.charAt(0).toUpperCase() + name.slice(1);\n  return params;\n};\n\nexports.template = 'app/meal.js.hbs';\n```\n\nNow our template is simpler, no more `{{params.food}}` and it\ncapitalizes our constructor like a propery lady or gent.\n\n_loom/templates/meal.js.hbs_\n\n```mustache\nfunction {{constructorName}}() {\n  this.food = '{{food}}';\n  this.venue = '{{venue}}';\n}\n```\n\nAnd finally our command is simpler, it now just matches a generator\nnamed `meal` instead of a template found at `app/meal.js`.\n\n`generate meal lunch food:taco venue:cart`\n\n### Engines\n\nThe default generator uses handlebars, but we can swap it out for ejs by\ncreating a very simple \"engine\":\n\n_loom/engines/ejs.js_\n\n```js\nvar _ = require('underscore');\n// module.exports = _.template\n// that works, but for clarity:\n\nmodule.exports = function(src, locals) {\n  return _.template(src, locals);\n};\n```\n\nRename your template to `meal.js.ejs` and edit it:\n\n```ejs\nfunction <%= constructorName %>() {\n  this.food = '<%= food %>';\n  this.venue = '<%= venue %>';\n}\n```\n\nUpdate your generator to point to the proper template:\n\n```js\nexports.template = 'app/meal.js.ejs';\n```\n\nLoom looks at the file extension of the template (in this case `ejs`)\nand then tries to find a template engine named `ejs.js`.\n\nNow generate your newly configured template:\n\n`generate meal lunch food:taco venue:cart`\n\n### Multiple templates for one generator\n\nIts very common for a generator to create several files, like unit tests\nand scaffoling. Lets add a unit test template to our meal generator.\n\n_loom/templates/test/unit/meal.spec.js.ejs_\n\n```ejs\ndescribe('<%= constructorName %>', function() {\n  it('sets food to \"<%= food %>\"', function() {\n    var meal = new <%= constructorName %>();\n    expect(meal.food).to.equal('<%= food %>');\n  });\n});\n```\n\nAnd add the template path to your generator, note the rename from\n`exports.template` to `export.templates`.\n\n```js\nexports.templates = [\n  'app/meal.js.ejs',\n  'test/unit/meal.spec.js.ejs'\n];\n```\n\nBoth templates will get the same data from `generator.present` and the\nfiles will be saved to the same relative path in your app as they are\ndefined in your templates directory.\n\n### Default Generators\n\nIf you define `loom/generators/default.js`, loom will use it when a\nspecific generator is not found.\n\nPublishing Generators to NPM for Everybody\n------------------------------------------\n\nName your module `loom-generators-<name>` (like\n`loom-generators-ember`), place generators, templates, and engines in\n`./loom`, and then publish.  That's it. People can simply `npm install\nloom-generators-<name> --save` and start using them.\n\nPublishing Template Engines to NPM for Everybody\n------------------------------------------------\n\nTo add support for your favorite templating engine you can either add a\nfile to `loom/engines` or publish a module to npm named\n`loom-engine-<ext>`. Loom will attempt to require the engine if it\ndoesn't find it in your project.\n\nGenerator API\n-------------\n\nLoom has a generic generator that can be overridden to meet your specific\nuse case. Generators can export a few methods that loom will use.\n\nYour generator can implement as many methods as you need, loom will\nmerge in the `generic_generator` methods that you don't provide.\n\nHere's a generator that does nothing:\n\n_loom/generators/noop.js_\n\n```js\nexports.before = function(){};\nexports.present = function(){};\nexports.savePath = function(){};\nexports.write = function(){};\nexports.render = function(){};\nexports.template = '';\n// exports.template = function(){};\n// exports.templates = [];\n// exports.templates = function(){};\n```\n\nBelow is documentation on generator API, also, check out the [generic\ngenerator](lib/generic_generator).\n\n### generator.before\n\nExecutes before anything else happens. Useful if you need to set or\nchange some things on `env` before it moves through the other methods of\nyour generator.\n\n#### signature\n\n`function(env)`\n\n#### arguments\n\n1. env (Object) - the loom environment object.\n\n\n### generator.present\n\n#### signature\n\n`function([argN] [, params], env)`\n\n#### arguments\n\n1. argN (String) - the space separated values used in the loom command\n2. params (Object) - the key:value pairs used in the loom command\n3. env (Object) - the loom environment object\n\n#### examples\n\nLets make a generator that logs the arguments to explore how this works.\n\n_loom/generators/user.js_\n\n```js\nexports.present = function() {\n  console.log(arguments);\n};\n```\n\nThe following are commands followed by what is logged for the arguments:\n\n```sh\ngenerate model user name:string age:number\n{ '0': 'user', '2': { name: 'string', age: 'number' } }\n\ngenerate model foo bar baz qux:1 quux:2\n{ '0': 'foo',\n  '1': 'bar',\n  '2': 'baz',\n  '3': { qux: '1', quux: '2' } }\n```\n\nAs you can see, the space separated values become the arguments and the\nkey=value pairs are wrapped up into an object for the final `params` argument.\n\n\n### generator.template\n\nDetermines which template to render.\n\n`exports.template` can simply be a string, or a function if you need to\ncompute it.\n\nPaths are relative to the `./loom/templates` directory.\n\n#### example\n\nTo use a template found at\n`loom/templates/spec/models/model.spec.js.hbs`:\n\n```js\nexports.template = 'spec/models/model.spec.js.hbs';\nexports.template = function() {\n  // some computation\n  return 'spec/models/model.spec.js.hbs';\n};\n```\n\n#### notes\n\nUnless you override `generator.write` the generated file will be saved\nin the mirrored location in `loom/templates`, so the example above will\nbe saved to `spec/models/<name>.spec.js`.\n\n### generator.templates\n\nSame as `template` but is an array of template paths that take\nprecendence over `template`. Each template will receive the same locals\nreturned from `present`. Can also be a function that returns an array.\n\n#### examples\n\n```js\nexports.templates = [\n  'app/models/model.js.ejs',\n  'spec/models/model.spec.js.ejs'\n];\n\nexports.templates = function() {\n  return [\n    'app/models/model.js.ejs',\n    'spec/models/model.spec.js.ejs'\n  ];\n};\n```\n\n### generator.savePath\n\nDetermines the path in which to save a template.\n\n#### signature\n\n`function(template, env)`\n\n#### arguments\n\n1. template (String) - the path of the template being rendered\n2. env (Object) - the loom environment object\n\n### generator.write\n\nWrites a rendered template to the file system, its unlikely you'll want\nto override this.\n\n#### signature\n\n`function(templateName, src, env)`\n\n### generator.render\n\nDetermines how to render the template, its unlinkely you'll want to\noverride this.\n\n#### signature\n\n`function(engine, templatePath, locals)`\n\nTODO\n====\n\n- --force option to overwrite files (better for scripting so you don't\n  get the prompt)\n- async compatibility, right now all generator operations must be\n  sync\n\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/rpflorence/loom/issues"},"homepage":"https://github.com/rpflorence/loom","_id":"loom@3.0.0-beta.2","dist":{"shasum":"d6bf2c6ad1974305e3aee58a0951abe5257c5e92","tarball":"https://registry.npmjs.org/loom/-/loom-3.0.0-beta.2.tgz","integrity":"sha512-w9G/pHaV0fwdK/mPUdj2UhSmdc/Lm0hT3nw6W2nF9NKbbRH3ZF7u/U7OI7EqCilH0NM/R7dMDJjHHtz9Vj87Dw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEbWSAaVqtxGycI/8A2RRf6Z1bKbbHr3PH3johw/8WAeAiEA4OORVNy/2cYUiIldCMXkgANdcd3nhRwbGkSttKvdCfc="}]},"_from":".","_npmVersion":"1.3.14","_npmUser":{"name":"ryanflorence","email":"rpflorence@gmail.com"},"maintainers":[{"name":"ryanflorence","email":"rpflorence+npm@gmail.com"}]},"3.0.0-beta.3":{"name":"loom","version":"3.0.0-beta.3","description":"Weave your wefts betwixt the warps of loom generators and scaffolds.","main":"loom.js","scripts":{"test":"node_modules/.bin/mocha --require should --reporter dot --ui bdd $(find test -name \"*.spec.js\")","watch":"node_modules/.bin/mocha --watch --require should --reporter dot --ui bdd $(find test -name \"*.spec.js\")"},"bin":{"generate":"./bin/generate"},"author":{"name":"Ryan Florence"},"license":"MIT","dependencies":{"commander":"~2.0.0","fs-extra":"~0.6.3","loom-engine-hbs":"2.0.0","cli-color":"~0.2.2","cli-prompt":"~0.3.2"},"devDependencies":{"mocha":"~1.12.0","sinon":"~1.7.3","should":"~1.2.2"},"repository":{"type":"git","url":"git://github.com/rpflorence/loom"},"keywords":["generator","scaffold","template","templating"],"readme":"Loom\n====\n\nWeave your wefts betwixt the warps of loom generators and scaffolds.\n\n![wefts and warps](http://ryanflorence.com/gifs/warp-weft.gif)\n\n**Loom makes it easy to share best-practices and common patterns for app\ndevelopment.**\n\n- build a set of generators for public consumption based on some\n  framework or library (like ember, angular, backbone, etc.)\n- consume those sets of generators\n- override those generators\n- build your own generators for your specific app\n\nUsing Loom Generator Packages from NPM\n--------------------------------------\n\nUsing generator packages from npm is easy:\n\n```sh\nnpm install loom-generators-ember --save\nnpm install loom-generators-ember-qunit --save\ngenerate controller user name:string age:number\n```\n\nThen refer to the documentation for the generators you've installed.\n\nYou must install with `--save` or add the module to your package.json\ninstead (that's how loom knows how to use them).\n\nIf two generator sets respond to the same commands, they will both be\nrun, allowing authors and consumers to compose them.\n\nCreating Your Own Generators\n----------------------------\n\nAlso, see [the full generator API below](#generator-api)\n\nWhile using generators others have created for you is great, its awesome\nto have a simple way to make generators for our own apps. Even if you're\nusing a set of generators from npm, defining your own generators will\noverride them.\n\n### Installation\n\n```sh\nnpm install loom -g\ngenerate --init\n```\n\n### Templates\n\nInitializing loom simply creates some directories in your project. After\nthat, all you need is a template in `./loom/templates/`:\n\nLets say we have a lot of \"meal\" objects in our app, lets make a\ntemplate for what one of these objects looks like:\n\n_loom/templates/app/meal.js.hbs_\n\n```mustache\nfunction {{objectName}}() {\n  this.food = '{{params.food}}';\n  this.venue = '{{params.venue}}';\n}\n```\n\nAnd then you can generate files based on the template:\n\n```sh\ngenerate app/meal.js lunch food:taco venue:cart\n```\n\nThis will create a file at `app/lunch.js` that looks like:\n\n```js\nfunction lunch() {\n  this.food = 'taco';\n  this.venue = 'cart';\n}\n```\n\nLoom, by default, will save files to your app in the same relative\nlocation they were found in your templates directory.\n\n### Generators\n\nWe can define a generator to make everything a little nicer. First we'll\ncreate a `present` method that determines what data goes to the\ntemplate. Then we'll tell it where to find the template so we can\nsimplify the generator command.\n\n_loom/generators/meal.js_\n\n```js\nexports.present = function(next, env) {\n  var locals = env.params;\n  var name = env.args[0];\n  locals.constructorName = name.charAt(0).toUpperCase() + name.slice(1);\n  return locals;\n};\n\nexports.template = 'app/meal.js.hbs';\n```\n\nNow our template is simpler, no more `{{params.food}}` and it\ncapitalizes our constructor like a proper lady or gent.\n\n_loom/templates/meal.js.hbs_\n\n```mustache\nfunction {{constructorName}}() {\n  this.food = '{{food}}';\n  this.venue = '{{venue}}';\n}\n```\n\nAnd finally our command is simpler, it now just matches a generator\nnamed `meal` instead of a template found at `app/meal.js`.\n\n`generate meal lunch food:taco venue:cart`\n\n### Engines\n\nThe default generator uses handlebars, but we can swap it out for ejs by\ncreating a very simple \"engine\":\n\n_loom/engines/ejs.js_\n\n```js\nvar _ = require('underscore');\n// module.exports = _.template\n// that works, but for clarity:\n\nmodule.exports = function(src, locals, callback) {\n  callback(_.template(src, locals));\n};\n```\n\nRename your template to `meal.js.ejs` and edit it:\n\n```ejs\nfunction <%= constructorName %>() {\n  this.food = '<%= food %>';\n  this.venue = '<%= venue %>';\n}\n```\n\nUpdate your generator to point to the proper template:\n\n```js\nexports.template = 'app/meal.js.ejs';\n```\n\nLoom looks at the file extension of the template (in this case `ejs`)\nand then tries to find a template engine named `ejs.js`.\n\nNow generate your newly configured template:\n\n`generate meal lunch food:taco venue:cart`\n\n### Multiple templates for one generator\n\nIts very common for a generator to create several files, like unit tests\nand scaffoling. Lets add a unit test template to our meal generator.\n\n_loom/templates/test/unit/meal.spec.js.ejs_\n\n```ejs\ndescribe('<%= constructorName %>', function() {\n  it('sets food to \"<%= food %>\"', function() {\n    var meal = new <%= constructorName %>();\n    expect(meal.food).to.equal('<%= food %>');\n  });\n});\n```\n\nAnd add the template path to your generator, note the rename from\n`exports.template` to `export.templates`.\n\n```js\nexports.templates = [\n  'app/meal.js.ejs',\n  'test/unit/meal.spec.js.ejs'\n];\n```\n\nBoth templates will get the same data from `generator.present` and the\nfiles will be saved to the same relative path in your app as they are\ndefined in your templates directory.\n\n### Default Generators\n\nIf you define `loom/generators/default.js`, loom will use it when a\nspecific generator is not found.\n\n\nPublishing Generators to NPM for Everybody\n------------------------------------------\n\nName your module `loom-generators-<name>` (like\n`loom-generators-ember`), place generators, templates, and engines in\n`./loom`, and then publish.  That's it. People can simply `npm install\nloom-generators-<name> --save` and start using them.\n\nPublishing Template Engines to NPM for Everybody\n------------------------------------------------\n\nTo add support for your favorite templating engine you can either add a\nfile to `loom/engines` or publish a module to npm named\n`loom-engine-<ext>`. Loom will attempt to require the engine if it\ndoesn't find it in your project.\n\nGenerator API\n-------------\n\nLoom has a generic generator that can be overridden to meet your specific\nuse case. Generators can export a few methods that loom will use.\n\nYour generator can implement as many methods as you need, loom will\nmerge in the `generic_generator` methods that you don't provide.\n\nHere's a generator that does nothing:\n\n_loom/generators/noop.js_\n\n```js\nexports.before = function(){};\nexports.present = function(){};\nexports.savePath = function(){};\nexports.write = function(){};\nexports.render = function(){};\nexports.template = '';\n// exports.template = function(){};\n// exports.templates = [];\n// exports.templates = function(){};\n```\n\nBelow is documentation on generator API, also, check out the [generic\ngenerator](lib/generic_generator).\n\nAll methods share the first two arguments: `next`, and `env`.\n\n- `next` - all methods are asynchronous, so when you're done doing what\n  you need to do, call `next(val)`.\n- `env` - the loom environment, it contains all sorts of information\n  about the `generate` command the user ran.\n\n### generator.before\n\nExecutes before anything else happens. Useful if you need to set or\nchange some things on `env` before it moves through the other methods of\nyour generator.\n\n#### signature\n\n`function(next, env)`\n\n\n1. next (Function) - the callback.\n2. env (Object) - the loom environment object.\n\n\n### generator.present\n\nYou're probably going to want `env.args` and `env.params`.\n\n#### signature\n\n`function(next, env)`\n\n#### arguments\n\n1. next (Function) - the callback.\n2. env (Object) - the loom environment object.\n\n#### examples\n\nLets make a generator that logs the arguments to explore how this works.\n\n_loom/generators/user.js_\n\n```js\nexports.present = function(next, env) {\n  console.log(env);\n};\n```\n\nThe following are commands followed by what is logged for the arguments:\n\n```sh\ngenerate model user name:string age:number\n{ args: ['user'], params: { name: 'string', age: 'number' } }\n\ngenerate model foo bar baz qux:1 quux:2\n{ args: ['foo', 'bar', 'baz' ]\n  params: { qux: '1', quux: '2' } }\n```\n\nAs you can see, the space separated values become the `args` and the\nkey:value pairs are wrapped up into the `params` argument.\n\n\n### generator.template\n\nDetermines which template to render.\n\n`exports.template` can simply be a string, or a function if you need to\ncompute it.\n\nPaths are relative to the `./loom/templates` directory.\n\n#### example\n\nTo use a template found at\n`loom/templates/spec/models/model.spec.js.hbs`:\n\n```js\nexports.template = 'spec/models/model.spec.js.hbs';\nexports.template = function(next) {\n  // some computation\n  next('spec/models/model.spec.js.hbs');\n};\n```\n\n#### notes\n\nUnless you override `generator.write` the generated file will be saved\nin the mirrored location in `loom/templates`, so the example above will\nbe saved to `spec/models/<name>.spec.js`.\n\n### generator.templates\n\nSame as `template` but is an array of template paths that take\nprecendence over `template`. Each template will receive the same locals\nreturned from `present`. Can also be a function that calls back an array.\n\n#### examples\n\n```js\nexports.templates = [\n  'app/models/model.js.ejs',\n  'spec/models/model.spec.js.ejs'\n];\n\nexports.templates = function(next) {\n  next([\n    'app/models/model.js.ejs',\n    'spec/models/model.spec.js.ejs'\n  ]);\n};\n```\n\n### generator.savePath\n\nDetermines the path in which to save a template.\n\n#### signature\n\n`function(next, env, template)`\n\n#### arguments\n\n1. next (Function) - callback with the savePath you want\n2. env (Object) - the loom environment object\n3. template (String) - the path of the template being rendered\n\n### generator.write\n\nWrites a rendered template to the file system, its unlikely you'll want\nto override this.\n\n#### signature\n\n`function(next, env, savePath, src)`\n\n### generator.render\n\nDetermines how to render the template, its unlinkely you'll want to\noverride this.\n\n#### signature\n\n`function(next, env, engine, templatePath, locals)`\n\nTODO\n----\n\n- conflict resolution when two generators want to save to the same path\n- --force option to overwrite files (better for scripting so you don't\n  get the prompt)\n\nLicense and Copyright\n---------------------\n\nMIT Style license\n\n(c) 2013 Ryan Florence\n\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/rpflorence/loom/issues"},"homepage":"https://github.com/rpflorence/loom","_id":"loom@3.0.0-beta.3","dist":{"shasum":"8066d63c27c1f4cd1070ff45822ed32ac893bd0e","tarball":"https://registry.npmjs.org/loom/-/loom-3.0.0-beta.3.tgz","integrity":"sha512-6E5nPY4CRYqB4yMwCPge88J6XoEcT+f3EoS/rviieBNAqx1lG/5+noQR9Aemt0NyQ9Wf9fe//0Ldhn0o9Hgl1A==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCcR8ERHj7wvX/q98crQESWOP1Nakp4Vf4CgfKOxwotmgIhAPT27tBPN9liynEt3R7wszHJHjL19rkDoVG3zzjAhJfU"}]},"_from":".","_npmVersion":"1.3.14","_npmUser":{"name":"ryanflorence","email":"rpflorence@gmail.com"},"maintainers":[{"name":"ryanflorence","email":"rpflorence+npm@gmail.com"}]},"3.0.0":{"name":"loom","version":"3.0.0","description":"Weave your wefts betwixt the warps of loom generators and scaffolds.","main":"loom.js","scripts":{"test":"node_modules/.bin/mocha --require should --reporter dot --ui bdd $(find test -name \"*.spec.js\")","watch":"node_modules/.bin/mocha --watch --require should --reporter dot --ui bdd $(find test -name \"*.spec.js\")"},"bin":{"generate":"./bin/generate"},"author":{"name":"Ryan Florence"},"license":"MIT","dependencies":{"commander":"~2.0.0","fs-extra":"~0.6.3","loom-engine-hbs":"2.0.0","cli-color":"~0.2.2","cli-prompt":"~0.3.2"},"devDependencies":{"mocha":"~1.12.0","sinon":"~1.7.3","should":"~1.2.2"},"repository":{"type":"git","url":"git://github.com/rpflorence/loom"},"keywords":["generator","scaffold","template","templating"],"readme":"Loom\n====\n\nWeave your wefts betwixt the warps of loom generators and scaffolds.\n\n![wefts and warps](http://ryanflorence.com/gifs/warp-weft.gif)\n\n**Loom makes it easy to share best-practices and common patterns for app\ndevelopment.**\n\n- build a set of generators for public consumption based on some\n  framework or library (like ember, angular, backbone, etc.)\n- consume those sets of generators\n- override those generators\n- build your own generators for your specific app\n\nUsing Loom Generator Packages from NPM\n--------------------------------------\n\nUsing generator packages from npm is easy:\n\n```sh\nnpm install loom-generators-ember --save\nnpm install loom-generators-ember-qunit --save\ngenerate controller user name:string age:number\n```\n\nThen refer to the documentation for the generators you've installed.\n\nYou must install with `--save` or add the module to your package.json\ninstead (that's how loom knows how to use them).\n\nIf two generator sets respond to the same commands, they will both be\nrun, allowing authors and consumers to compose them.\n\nCreating Your Own Generators\n----------------------------\n\nAlso, see [the full generator API below](#generator-api)\n\nWhile using generators others have created for you is great, its awesome\nto have a simple way to make generators for our own apps. Even if you're\nusing a set of generators from npm, defining your own generators will\noverride them.\n\n### Installation\n\n```sh\nnpm install loom -g\ngenerate --init\n```\n\n### Templates\n\nInitializing loom simply creates some directories in your project. After\nthat, all you need is a template in `./loom/templates/`:\n\nLets say we have a lot of \"meal\" objects in our app, lets make a\ntemplate for what one of these objects looks like:\n\n_loom/templates/app/meal.js.hbs_\n\n```mustache\nfunction {{objectName}}() {\n  this.food = '{{params.food}}';\n  this.venue = '{{params.venue}}';\n}\n```\n\nAnd then you can generate files based on the template:\n\n```sh\ngenerate app/meal.js lunch food:taco venue:cart\n```\n\nThis will create a file at `app/lunch.js` that looks like:\n\n```js\nfunction lunch() {\n  this.food = 'taco';\n  this.venue = 'cart';\n}\n```\n\nLoom, by default, will save files to your app in the same relative\nlocation they were found in your templates directory.\n\n### Generators\n\nWe can define a generator to make everything a little nicer. First we'll\ncreate a `present` method that determines what data goes to the\ntemplate. Then we'll tell it where to find the template so we can\nsimplify the generator command.\n\n_loom/generators/meal.js_\n\n```js\nexports.present = function(next, env) {\n  var locals = env.params;\n  var name = env.args[0];\n  locals.constructorName = name.charAt(0).toUpperCase() + name.slice(1);\n  return locals;\n};\n\nexports.template = 'app/meal.js.hbs';\n```\n\nNow our template is simpler, no more `{{params.food}}` and it\ncapitalizes our constructor like a proper lady or gent.\n\n_loom/templates/meal.js.hbs_\n\n```mustache\nfunction {{constructorName}}() {\n  this.food = '{{food}}';\n  this.venue = '{{venue}}';\n}\n```\n\nAnd finally our command is simpler, it now just matches a generator\nnamed `meal` instead of a template found at `app/meal.js`.\n\n`generate meal lunch food:taco venue:cart`\n\n### Engines\n\nThe default generator uses handlebars, but we can swap it out for ejs by\ncreating a very simple \"engine\":\n\n_loom/engines/ejs.js_\n\n```js\nvar _ = require('underscore');\n// module.exports = _.template\n// that works, but for clarity:\n\nmodule.exports = function(src, locals, callback) {\n  callback(_.template(src, locals));\n};\n```\n\nRename your template to `meal.js.ejs` and edit it:\n\n```ejs\nfunction <%= constructorName %>() {\n  this.food = '<%= food %>';\n  this.venue = '<%= venue %>';\n}\n```\n\nUpdate your generator to point to the proper template:\n\n```js\nexports.template = 'app/meal.js.ejs';\n```\n\nLoom looks at the file extension of the template (in this case `ejs`)\nand then tries to find a template engine named `ejs.js`.\n\nNow generate your newly configured template:\n\n`generate meal lunch food:taco venue:cart`\n\n### Multiple templates for one generator\n\nIts very common for a generator to create several files, like unit tests\nand scaffoling. Lets add a unit test template to our meal generator.\n\n_loom/templates/test/unit/meal.spec.js.ejs_\n\n```ejs\ndescribe('<%= constructorName %>', function() {\n  it('sets food to \"<%= food %>\"', function() {\n    var meal = new <%= constructorName %>();\n    expect(meal.food).to.equal('<%= food %>');\n  });\n});\n```\n\nAnd add the template path to your generator, note the rename from\n`exports.template` to `export.templates`.\n\n```js\nexports.templates = [\n  'app/meal.js.ejs',\n  'test/unit/meal.spec.js.ejs'\n];\n```\n\nBoth templates will get the same data from `generator.present` and the\nfiles will be saved to the same relative path in your app as they are\ndefined in your templates directory.\n\n### Default Generators\n\nIf you define `loom/generators/default.js`, loom will use it when a\nspecific generator is not found.\n\n\nPublishing Generators to NPM for Everybody\n------------------------------------------\n\nName your module `loom-generators-<name>` (like\n`loom-generators-ember`), place generators, templates, and engines in\n`./loom`, and then publish.  That's it. People can simply `npm install\nloom-generators-<name> --save` and start using them.\n\nPublishing Template Engines to NPM for Everybody\n------------------------------------------------\n\nTo add support for your favorite templating engine you can either add a\nfile to `loom/engines` or publish a module to npm named\n`loom-engine-<ext>`. Loom will attempt to require the engine if it\ndoesn't find it in your project.\n\nGenerator API\n-------------\n\nLoom has a generic generator that can be overridden to meet your specific\nuse case. Generators can export a few methods that loom will use.\n\nYour generator can implement as many methods as you need, loom will\nmerge in the `generic_generator` methods that you don't provide.\n\nHere's a generator that does nothing:\n\n_loom/generators/noop.js_\n\n```js\nexports.before = function(){};\nexports.present = function(){};\nexports.savePath = function(){};\nexports.write = function(){};\nexports.render = function(){};\nexports.template = '';\n// exports.template = function(){};\n// exports.templates = [];\n// exports.templates = function(){};\n```\n\nBelow is documentation on generator API, also, check out the [generic\ngenerator](lib/generic_generator).\n\nAll methods share the first two arguments: `next`, and `env`.\n\n- `next` - all methods are asynchronous, so when you're done doing what\n  you need to do, call `next(val)`.\n- `env` - the loom environment, it contains all sorts of information\n  about the `generate` command the user ran.\n\n### generator.before\n\nExecutes before anything else happens. Useful if you need to set or\nchange some things on `env` before it moves through the other methods of\nyour generator.\n\n#### signature\n\n`function(next, env)`\n\n\n1. next (Function) - the callback.\n2. env (Object) - the loom environment object.\n\n\n### generator.present\n\nYou're probably going to want `env.args` and `env.params`.\n\n#### signature\n\n`function(next, env)`\n\n#### arguments\n\n1. next (Function) - the callback.\n2. env (Object) - the loom environment object.\n\n#### examples\n\nLets make a generator that logs the arguments to explore how this works.\n\n_loom/generators/user.js_\n\n```js\nexports.present = function(next, env) {\n  console.log(env);\n};\n```\n\nThe following are commands followed by what is logged for the arguments:\n\n```sh\ngenerate model user name:string age:number\n{ args: ['user'], params: { name: 'string', age: 'number' } }\n\ngenerate model foo bar baz qux:1 quux:2\n{ args: ['foo', 'bar', 'baz' ]\n  params: { qux: '1', quux: '2' } }\n```\n\nAs you can see, the space separated values become the `args` and the\nkey:value pairs are wrapped up into the `params` argument.\n\n\n### generator.template\n\nDetermines which template to render.\n\n`exports.template` can simply be a string, or a function if you need to\ncompute it.\n\nPaths are relative to the `./loom/templates` directory.\n\n#### example\n\nTo use a template found at\n`loom/templates/spec/models/model.spec.js.hbs`:\n\n```js\nexports.template = 'spec/models/model.spec.js.hbs';\nexports.template = function(next) {\n  // some computation\n  next('spec/models/model.spec.js.hbs');\n};\n```\n\n#### notes\n\nUnless you override `generator.write` the generated file will be saved\nin the mirrored location in `loom/templates`, so the example above will\nbe saved to `spec/models/<name>.spec.js`.\n\n### generator.templates\n\nSame as `template` but is an array of template paths that take\nprecendence over `template`. Each template will receive the same locals\nreturned from `present`. Can also be a function that calls back an array.\n\n#### examples\n\n```js\nexports.templates = [\n  'app/models/model.js.ejs',\n  'spec/models/model.spec.js.ejs'\n];\n\nexports.templates = function(next) {\n  next([\n    'app/models/model.js.ejs',\n    'spec/models/model.spec.js.ejs'\n  ]);\n};\n```\n\n### generator.savePath\n\nDetermines the path in which to save a template.\n\n#### signature\n\n`function(next, env, template)`\n\n#### arguments\n\n1. next (Function) - callback with the savePath you want\n2. env (Object) - the loom environment object\n3. template (String) - the path of the template being rendered\n\n### generator.write\n\nWrites a rendered template to the file system, its unlikely you'll want\nto override this.\n\n#### signature\n\n`function(next, env, savePath, src)`\n\n### generator.render\n\nDetermines how to render the template, its unlinkely you'll want to\noverride this.\n\n#### signature\n\n`function(next, env, engine, templatePath, locals)`\n\nTODO\n----\n\n- conflict resolution when two generators want to save to the same path\n- --force option to overwrite files (better for scripting so you don't\n  get the prompt)\n\nLicense and Copyright\n---------------------\n\nMIT Style license\n\n(c) 2013 Ryan Florence\n\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/rpflorence/loom/issues"},"homepage":"https://github.com/rpflorence/loom","_id":"loom@3.0.0","dist":{"shasum":"9cf6ffd97148b1b873320516cb196af3dacda2f1","tarball":"https://registry.npmjs.org/loom/-/loom-3.0.0.tgz","integrity":"sha512-DuCmMvdJPwopeY2zLRqO10JCIjzLOpB5H6ze4xNcp9qKDvT0Q4vRsSvcF6DzVjd/lXG85jtq2hMkOjqmRPwtkA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDEF+FK+inWGTimp0gESI69BHfQ9R5ZU7oimX3rveBFcQIgEt/PGiJ0PwH/uAaYFR/78MRGYGqLh15AyF2cBc5NpSA="}]},"_from":".","_npmVersion":"1.3.14","_npmUser":{"name":"ryanflorence","email":"rpflorence@gmail.com"},"maintainers":[{"name":"ryanflorence","email":"rpflorence+npm@gmail.com"}]},"3.0.1":{"name":"loom","version":"3.0.1","description":"Weave your wefts betwixt the warps of loom generators and scaffolds.","main":"loom.js","scripts":{"test":"node_modules/.bin/mocha --require should --reporter dot --ui bdd $(find test -name \"*.spec.js\")","watch":"node_modules/.bin/mocha --watch --require should --reporter dot --ui bdd $(find test -name \"*.spec.js\")"},"bin":{"generate":"./bin/generate"},"author":{"name":"Ryan Florence"},"license":"MIT","dependencies":{"commander":"~2.0.0","fs-extra":"~0.6.3","loom-engine-hbs":"2.0.0","cli-color":"~0.2.2","cli-prompt":"~0.3.2","async":"~0.2.9"},"devDependencies":{"mocha":"~1.12.0","sinon":"~1.7.3","should":"~1.2.2"},"repository":{"type":"git","url":"git://github.com/rpflorence/loom"},"keywords":["generator","scaffold","template","templating"],"readme":"Loom\n====\n\nWeave your wefts betwixt the warps of loom generators and scaffolds.\n\n![wefts and warps](http://ryanflorence.com/gifs/warp-weft.gif)\n\n**Loom makes it easy to share best-practices and common patterns for app\ndevelopment.**\n\n- build a set of generators for public consumption based on some\n  framework or library (like ember, angular, backbone, etc.)\n- consume those sets of generators\n- override those generators\n- build your own generators for your specific app\n\nUsing Loom Generator Packages from NPM\n--------------------------------------\n\nUsing generator packages from npm is easy:\n\n```sh\nnpm install loom-generators-ember --save\nnpm install loom-generators-ember-qunit --save\ngenerate controller user name:string age:number\n```\n\nThen refer to the documentation for the generators you've installed.\n\nYou must install with `--save` or add the module to your package.json\ninstead (that's how loom knows how to use them).\n\nIf two generator sets respond to the same commands, they will both be\nrun, allowing authors and consumers to compose them.\n\nCreating Your Own Generators\n----------------------------\n\nAlso, see [the full generator API below](#generator-api)\n\nWhile using generators others have created for you is great, its awesome\nto have a simple way to make generators for our own apps. Even if you're\nusing a set of generators from npm, defining your own generators will\noverride them.\n\n### Installation\n\n```sh\nnpm install loom -g\ngenerate --init\n```\n\n### Templates\n\nInitializing loom simply creates some directories in your project. After\nthat, all you need is a template in `./loom/templates/`:\n\nLets say we have a lot of \"meal\" objects in our app, lets make a\ntemplate for what one of these objects looks like:\n\n_loom/templates/app/meal.js.hbs_\n\n```mustache\nfunction {{objectName}}() {\n  this.food = '{{params.food}}';\n  this.venue = '{{params.venue}}';\n}\n```\n\nAnd then you can generate files based on the template:\n\n```sh\ngenerate app/meal.js lunch food:taco venue:cart\n```\n\nThis will create a file at `app/lunch.js` that looks like:\n\n```js\nfunction lunch() {\n  this.food = 'taco';\n  this.venue = 'cart';\n}\n```\n\nLoom, by default, will save files to your app in the same relative\nlocation they were found in your templates directory.\n\n### Generators\n\nWe can define a generator to make everything a little nicer. First we'll\ncreate a `present` method that determines what data goes to the\ntemplate. Then we'll tell it where to find the template so we can\nsimplify the generator command.\n\n_loom/generators/meal.js_\n\n```js\nexports.present = function(next, env) {\n  var locals = env.params;\n  var name = env.args[0];\n  locals.constructorName = name.charAt(0).toUpperCase() + name.slice(1);\n  return locals;\n};\n\nexports.template = 'app/meal.js.hbs';\n```\n\nNow our template is simpler, no more `{{params.food}}` and it\ncapitalizes our constructor like a proper lady or gent.\n\n_loom/templates/meal.js.hbs_\n\n```mustache\nfunction {{constructorName}}() {\n  this.food = '{{food}}';\n  this.venue = '{{venue}}';\n}\n```\n\nAnd finally our command is simpler, it now just matches a generator\nnamed `meal` instead of a template found at `app/meal.js`.\n\n`generate meal lunch food:taco venue:cart`\n\n### Engines\n\nThe default generator uses handlebars, but we can swap it out for ejs by\ncreating a very simple \"engine\":\n\n_loom/engines/ejs.js_\n\n```js\nvar _ = require('underscore');\n// module.exports = _.template\n// that works, but for clarity:\n\nmodule.exports = function(src, locals, callback) {\n  callback(_.template(src, locals));\n};\n```\n\nRename your template to `meal.js.ejs` and edit it:\n\n```ejs\nfunction <%= constructorName %>() {\n  this.food = '<%= food %>';\n  this.venue = '<%= venue %>';\n}\n```\n\nUpdate your generator to point to the proper template:\n\n```js\nexports.template = 'app/meal.js.ejs';\n```\n\nLoom looks at the file extension of the template (in this case `ejs`)\nand then tries to find a template engine named `ejs.js`.\n\nNow generate your newly configured template:\n\n`generate meal lunch food:taco venue:cart`\n\n### Multiple templates for one generator\n\nIts very common for a generator to create several files, like unit tests\nand scaffoling. Lets add a unit test template to our meal generator.\n\n_loom/templates/test/unit/meal.spec.js.ejs_\n\n```ejs\ndescribe('<%= constructorName %>', function() {\n  it('sets food to \"<%= food %>\"', function() {\n    var meal = new <%= constructorName %>();\n    expect(meal.food).to.equal('<%= food %>');\n  });\n});\n```\n\nAnd add the template path to your generator, note the rename from\n`exports.template` to `export.templates`.\n\n```js\nexports.templates = [\n  'app/meal.js.ejs',\n  'test/unit/meal.spec.js.ejs'\n];\n```\n\nBoth templates will get the same data from `generator.present` and the\nfiles will be saved to the same relative path in your app as they are\ndefined in your templates directory.\n\n### Default Generators\n\nIf you define `loom/generators/default.js`, loom will use it when a\nspecific generator is not found.\n\n\nPublishing Generators to NPM for Everybody\n------------------------------------------\n\nName your module `loom-generators-<name>` (like\n`loom-generators-ember`), place generators, templates, and engines in\n`./loom`, and then publish.  That's it. People can simply `npm install\nloom-generators-<name> --save` and start using them.\n\nPublishing Template Engines to NPM for Everybody\n------------------------------------------------\n\nTo add support for your favorite templating engine you can either add a\nfile to `loom/engines` or publish a module to npm named\n`loom-engine-<ext>`. Loom will attempt to require the engine if it\ndoesn't find it in your project.\n\nGenerator API\n-------------\n\nLoom has a generic generator that can be overridden to meet your specific\nuse case. Generators can export a few methods that loom will use.\n\nYour generator can implement as many methods as you need, loom will\nmerge in the `generic_generator` methods that you don't provide.\n\nHere's a generator that does nothing:\n\n_loom/generators/noop.js_\n\n```js\nexports.before = function(){};\nexports.present = function(){};\nexports.savePath = function(){};\nexports.write = function(){};\nexports.render = function(){};\nexports.template = '';\n// exports.template = function(){};\n// exports.templates = [];\n// exports.templates = function(){};\n```\n\nBelow is documentation on generator API, also, check out the [generic\ngenerator](lib/generic_generator).\n\nAll methods share the first two arguments: `next`, and `env`.\n\n- `next` - all methods are asynchronous, so when you're done doing what\n  you need to do, call `next(val)`.\n- `env` - the loom environment, it contains all sorts of information\n  about the `generate` command the user ran.\n\n### generator.before\n\nExecutes before anything else happens. Useful if you need to set or\nchange some things on `env` before it moves through the other methods of\nyour generator.\n\n#### signature\n\n`function(next, env)`\n\n\n1. next (Function) - the callback.\n2. env (Object) - the loom environment object.\n\n\n### generator.present\n\nYou're probably going to want `env.args` and `env.params`.\n\n#### signature\n\n`function(next, env)`\n\n#### arguments\n\n1. next (Function) - the callback.\n2. env (Object) - the loom environment object.\n\n#### examples\n\nLets make a generator that logs the arguments to explore how this works.\n\n_loom/generators/user.js_\n\n```js\nexports.present = function(next, env) {\n  console.log(env);\n};\n```\n\nThe following are commands followed by what is logged for the arguments:\n\n```sh\ngenerate model user name:string age:number\n{ args: ['user'], params: { name: 'string', age: 'number' } }\n\ngenerate model foo bar baz qux:1 quux:2\n{ args: ['foo', 'bar', 'baz' ]\n  params: { qux: '1', quux: '2' } }\n```\n\nAs you can see, the space separated values become the `args` and the\nkey:value pairs are wrapped up into the `params` argument.\n\n\n### generator.template\n\nDetermines which template to render.\n\n`exports.template` can simply be a string, or a function if you need to\ncompute it.\n\nPaths are relative to the `./loom/templates` directory.\n\n#### example\n\nTo use a template found at\n`loom/templates/spec/models/model.spec.js.hbs`:\n\n```js\nexports.template = 'spec/models/model.spec.js.hbs';\nexports.template = function(next) {\n  // some computation\n  next('spec/models/model.spec.js.hbs');\n};\n```\n\n#### notes\n\nUnless you override `generator.write` the generated file will be saved\nin the mirrored location in `loom/templates`, so the example above will\nbe saved to `spec/models/<name>.spec.js`.\n\n### generator.templates\n\nSame as `template` but is an array of template paths that take\nprecendence over `template`. Each template will receive the same locals\nreturned from `present`. Can also be a function that calls back an array.\n\n#### examples\n\n```js\nexports.templates = [\n  'app/models/model.js.ejs',\n  'spec/models/model.spec.js.ejs'\n];\n\nexports.templates = function(next) {\n  next([\n    'app/models/model.js.ejs',\n    'spec/models/model.spec.js.ejs'\n  ]);\n};\n```\n\n### generator.savePath\n\nDetermines the path in which to save a template.\n\n#### signature\n\n`function(next, env, template)`\n\n#### arguments\n\n1. next (Function) - callback with the savePath you want\n2. env (Object) - the loom environment object\n3. template (String) - the path of the template being rendered\n\n### generator.write\n\nWrites a rendered template to the file system, its unlikely you'll want\nto override this.\n\n#### signature\n\n`function(next, env, savePath, src)`\n\n### generator.render\n\nDetermines how to render the template, its unlinkely you'll want to\noverride this.\n\n#### signature\n\n`function(next, env, engine, templatePath, locals)`\n\nTODO\n----\n\n- conflict resolution when two generators want to save to the same path\n- --force option to overwrite files (better for scripting so you don't\n  get the prompt)\n\nLicense and Copyright\n---------------------\n\nMIT Style license\n\n(c) 2013 Ryan Florence\n\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/rpflorence/loom/issues"},"homepage":"https://github.com/rpflorence/loom","_id":"loom@3.0.1","dist":{"shasum":"c6fab924e9b0545b8a4ffaecda7ab7c22f0672e2","tarball":"https://registry.npmjs.org/loom/-/loom-3.0.1.tgz","integrity":"sha512-0Fstqv9uiVMsH/d3R4IecRJABpnY6smlcqpUr4eXrtSYTp/FMC7lSPLN/8GiXwdgwgQlVzSgJy2ViEJOeIe0ew==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDc499QJwPh1PIbTim6gCdj8USXehOxesxNW2Mf4cNumwIhAO8iSfGr8UxwSXofCzyvyWQKXhdVYdp+tne4Bh1H1/9q"}]},"_from":".","_npmVersion":"1.3.14","_npmUser":{"name":"ryanflorence","email":"rpflorence@gmail.com"},"maintainers":[{"name":"ryanflorence","email":"rpflorence+npm@gmail.com"}]},"3.0.2":{"name":"loom","version":"3.0.2","description":"Weave your wefts betwixt the warps of loom generators and scaffolds.","main":"loom.js","scripts":{"test":"node_modules/.bin/mocha --require should --reporter dot --ui bdd $(find test -name \"*.spec.js\")","watch":"node_modules/.bin/mocha --watch --require should --reporter dot --ui bdd $(find test -name \"*.spec.js\")"},"bin":{"generate":"./bin/generate"},"author":{"name":"Ryan Florence"},"license":"MIT","dependencies":{"commander":"~2.0.0","fs-extra":"~0.6.3","loom-engine-hbs":"2.0.0","cli-color":"~0.2.2","cli-prompt":"~0.3.2","async":"~0.2.9"},"devDependencies":{"mocha":"~1.12.0","sinon":"~1.7.3","should":"~1.2.2"},"repository":{"type":"git","url":"git://github.com/rpflorence/loom"},"keywords":["generator","scaffold","template","templating"],"readme":"Loom\n====\n\nWeave your wefts betwixt the warps of loom generators and scaffolds.\n\n![wefts and warps](http://ryanflorence.com/gifs/warp-weft.gif)\n\n**Loom makes it easy to share best-practices and common patterns for app\ndevelopment.**\n\n- build a set of generators for public consumption based on some\n  framework or library (like ember, angular, backbone, etc.)\n- consume those sets of generators\n- override those generators\n- build your own generators for your specific app\n\nUsing Loom Generator Packages from NPM\n--------------------------------------\n\nUsing generator packages from npm is easy:\n\n```sh\nnpm install loom-generators-ember --save\nnpm install loom-generators-ember-qunit --save\ngenerate controller user name:string age:number\n```\n\nThen refer to the documentation for the generators you've installed.\n\nYou must install with `--save` or add the module to your package.json\ninstead (that's how loom knows how to use them).\n\nIf two generator sets respond to the same commands, they will both be\nrun, allowing authors and consumers to compose them.\n\nCreating Your Own Generators\n----------------------------\n\nAlso, see [the full generator API below](#generator-api)\n\nWhile using generators others have created for you is great, its awesome\nto have a simple way to make generators for our own apps. Even if you're\nusing a set of generators from npm, defining your own generators will\noverride them.\n\n### Installation\n\n```sh\nnpm install loom -g\ngenerate --init\n```\n\n### Templates\n\nInitializing loom simply creates some directories in your project. After\nthat, all you need is a template in `./loom/templates/`:\n\nLets say we have a lot of \"meal\" objects in our app, lets make a\ntemplate for what one of these objects looks like:\n\n_loom/templates/app/meal.js.hbs_\n\n```mustache\nfunction {{objectName}}() {\n  this.food = '{{params.food}}';\n  this.venue = '{{params.venue}}';\n}\n```\n\nAnd then you can generate files based on the template:\n\n```sh\ngenerate app/meal.js lunch food:taco venue:cart\n```\n\nThis will create a file at `app/lunch.js` that looks like:\n\n```js\nfunction lunch() {\n  this.food = 'taco';\n  this.venue = 'cart';\n}\n```\n\nLoom, by default, will save files to your app in the same relative\nlocation they were found in your templates directory.\n\n### Generators\n\nWe can define a generator to make everything a little nicer. First we'll\ncreate a `present` method that determines what data goes to the\ntemplate. Then we'll tell it where to find the template so we can\nsimplify the generator command.\n\n_loom/generators/meal.js_\n\n```js\nexports.present = function(next, env) {\n  var locals = env.params;\n  var name = env.args[0];\n  locals.constructorName = name.charAt(0).toUpperCase() + name.slice(1);\n  return locals;\n};\n\nexports.template = 'app/meal.js.hbs';\n```\n\nNow our template is simpler, no more `{{params.food}}` and it\ncapitalizes our constructor like a proper lady or gent.\n\n_loom/templates/meal.js.hbs_\n\n```mustache\nfunction {{constructorName}}() {\n  this.food = '{{food}}';\n  this.venue = '{{venue}}';\n}\n```\n\nAnd finally our command is simpler, it now just matches a generator\nnamed `meal` instead of a template found at `app/meal.js`.\n\n`generate meal lunch food:taco venue:cart`\n\n### Engines\n\nThe default generator uses handlebars, but we can swap it out for ejs by\ncreating a very simple \"engine\":\n\n_loom/engines/ejs.js_\n\n```js\nvar _ = require('underscore');\n// module.exports = _.template\n// that works, but for clarity:\n\nmodule.exports = function(src, locals, callback) {\n  callback(_.template(src, locals));\n};\n```\n\nRename your template to `meal.js.ejs` and edit it:\n\n```ejs\nfunction <%= constructorName %>() {\n  this.food = '<%= food %>';\n  this.venue = '<%= venue %>';\n}\n```\n\nUpdate your generator to point to the proper template:\n\n```js\nexports.template = 'app/meal.js.ejs';\n```\n\nLoom looks at the file extension of the template (in this case `ejs`)\nand then tries to find a template engine named `ejs.js`.\n\nNow generate your newly configured template:\n\n`generate meal lunch food:taco venue:cart`\n\n### Multiple templates for one generator\n\nIts very common for a generator to create several files, like unit tests\nand scaffoling. Lets add a unit test template to our meal generator.\n\n_loom/templates/test/unit/meal.spec.js.ejs_\n\n```ejs\ndescribe('<%= constructorName %>', function() {\n  it('sets food to \"<%= food %>\"', function() {\n    var meal = new <%= constructorName %>();\n    expect(meal.food).to.equal('<%= food %>');\n  });\n});\n```\n\nAnd add the template path to your generator, note the rename from\n`exports.template` to `export.templates`.\n\n```js\nexports.templates = [\n  'app/meal.js.ejs',\n  'test/unit/meal.spec.js.ejs'\n];\n```\n\nBoth templates will get the same data from `generator.present` and the\nfiles will be saved to the same relative path in your app as they are\ndefined in your templates directory.\n\n### Default Generators\n\nIf you define `loom/generators/default.js`, loom will use it when a\nspecific generator is not found.\n\n\nPublishing Generators to NPM for Everybody\n------------------------------------------\n\nName your module `loom-generators-<name>` (like\n`loom-generators-ember`), place generators, templates, and engines in\n`./loom`, and then publish.  That's it. People can simply `npm install\nloom-generators-<name> --save` and start using them.\n\nPublishing Template Engines to NPM for Everybody\n------------------------------------------------\n\nTo add support for your favorite templating engine you can either add a\nfile to `loom/engines` or publish a module to npm named\n`loom-engine-<ext>`. Loom will attempt to require the engine if it\ndoesn't find it in your project.\n\nGenerator API\n-------------\n\nLoom has a generic generator that can be overridden to meet your specific\nuse case. Generators can export a few methods that loom will use.\n\nYour generator can implement as many methods as you need, loom will\nmerge in the `generic_generator` methods that you don't provide.\n\nHere's a generator that does nothing:\n\n_loom/generators/noop.js_\n\n```js\nexports.before = function(){};\nexports.after = function(){};\nexports.present = function(){};\nexports.savePath = function(){};\nexports.write = function(){};\nexports.render = function(){};\nexports.template = '';\n// exports.template = function(){};\n// exports.templates = [];\n// exports.templates = function(){};\n```\n\nBelow is documentation on generator API, also, check out the [generic\ngenerator](lib/generic_generator).\n\nAll methods share the first two arguments: `next`, and `env`.\n\n- `next` - all methods are asynchronous, so when you're done doing what\n  you need to do, call `next(val)`.\n- `env` - the loom environment, it contains all sorts of information\n  about the `generate` command the user ran.\n\n### generator.before\n\nExecutes before anything else happens. Useful if you need to set or\nchange some things on `env` before it moves through the other methods of\nyour generator.\n\n#### signature\n\n`function(next, env)`\n\n1. next (Function) - the callback.\n2. env (Object) - the loom environment object.\n\n\n### generator.after\n\nExecutes after everything else happens. Useful if you want to give the\nuser some instructions about the files they just generated.\n\n#### signature\n\n`function(next, env)`\n\n1. next (Function) - the callback.\n2. env (Object) - the loom environment object.\n\n\n### generator.present\n\nYou're probably going to want `env.args` and `env.params`.\n\n#### signature\n\n`function(next, env)`\n\n#### arguments\n\n1. next (Function) - the callback.\n2. env (Object) - the loom environment object.\n\n#### examples\n\nLets make a generator that logs the arguments to explore how this works.\n\n_loom/generators/user.js_\n\n```js\nexports.present = function(next, env) {\n  console.log(env);\n};\n```\n\nThe following are commands followed by what is logged for the arguments:\n\n```sh\ngenerate model user name:string age:number\n{ args: ['user'], params: { name: 'string', age: 'number' } }\n\ngenerate model foo bar baz qux:1 quux:2\n{ args: ['foo', 'bar', 'baz' ]\n  params: { qux: '1', quux: '2' } }\n```\n\nAs you can see, the space separated values become the `args` and the\nkey:value pairs are wrapped up into the `params` argument.\n\n\n### generator.template\n\nDetermines which template to render.\n\n`exports.template` can simply be a string, or a function if you need to\ncompute it.\n\nPaths are relative to the `./loom/templates` directory.\n\n#### example\n\nTo use a template found at\n`loom/templates/spec/models/model.spec.js.hbs`:\n\n```js\nexports.template = 'spec/models/model.spec.js.hbs';\nexports.template = function(next) {\n  // some computation\n  next('spec/models/model.spec.js.hbs');\n};\n```\n\n#### notes\n\nUnless you override `generator.write` the generated file will be saved\nin the mirrored location in `loom/templates`, so the example above will\nbe saved to `spec/models/<name>.spec.js`.\n\n### generator.templates\n\nSame as `template` but is an array of template paths that take\nprecendence over `template`. Each template will receive the same locals\nreturned from `present`. Can also be a function that calls back an array.\n\n#### examples\n\n```js\nexports.templates = [\n  'app/models/model.js.ejs',\n  'spec/models/model.spec.js.ejs'\n];\n\nexports.templates = function(next) {\n  next([\n    'app/models/model.js.ejs',\n    'spec/models/model.spec.js.ejs'\n  ]);\n};\n```\n\n### generator.savePath\n\nDetermines the path in which to save a template.\n\n#### signature\n\n`function(next, env, template)`\n\n#### arguments\n\n1. next (Function) - callback with the savePath you want\n2. env (Object) - the loom environment object\n3. template (String) - the path of the template being rendered\n\n### generator.write\n\nWrites a rendered template to the file system, its unlikely you'll want\nto override this.\n\n#### signature\n\n`function(next, env, savePath, src)`\n\n### generator.render\n\nDetermines how to render the template, its unlinkely you'll want to\noverride this.\n\n#### signature\n\n`function(next, env, engine, templatePath, locals)`\n\nTODO\n----\n\n- conflict resolution when two generators want to save to the same path\n- --force option to overwrite files (better for scripting so you don't\n  get the prompt)\n\nLicense and Copyright\n---------------------\n\nMIT Style license\n\n(c) 2013 Ryan Florence\n\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/rpflorence/loom/issues"},"homepage":"https://github.com/rpflorence/loom","_id":"loom@3.0.2","dist":{"shasum":"c26a68ff8ef47be54d1c758fcf614135f7ab202d","tarball":"https://registry.npmjs.org/loom/-/loom-3.0.2.tgz","integrity":"sha512-lbSHVfABCl9o7tJB6a+yiZ7veLXs/3GG644P1rYMRooRiZPZfxANi5zFYtBomPPcdEoPIekzuWV5vpbQJjXwwA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDheSOyQKGC4JwF3+q3X9GVTf48/YT83POmCz4dSBbYyAiEA0M8A95mhRQPXKMAlrrNe+achrmoIgtTmoQpMq280q5Y="}]},"_from":".","_npmVersion":"1.3.14","_npmUser":{"name":"ryanflorence","email":"rpflorence@gmail.com"},"maintainers":[{"name":"ryanflorence","email":"rpflorence+npm@gmail.com"}]},"3.0.3":{"name":"loom","version":"3.0.3","description":"Weave your wefts betwixt the warps of loom generators and scaffolds.","main":"loom.js","scripts":{"test":"node_modules/.bin/mocha --require should --reporter dot --ui bdd $(find test -name \"*.spec.js\")","watch":"node_modules/.bin/mocha --watch --require should --reporter dot --ui bdd $(find test -name \"*.spec.js\")"},"bin":{"generate":"./bin/generate"},"author":{"name":"Ryan Florence"},"license":"MIT","dependencies":{"commander":"~2.0.0","fs-extra":"~0.6.3","loom-engine-hbs":"2.0.0","cli-color":"~0.2.2","cli-prompt":"~0.3.2","async":"~0.2.9"},"devDependencies":{"mocha":"~1.12.0","sinon":"~1.7.3","should":"~1.2.2"},"repository":{"type":"git","url":"git://github.com/rpflorence/loom"},"keywords":["generator","scaffold","template","templating"],"readme":"Loom\n====\n\nWeave your wefts betwixt the warps of loom generators and scaffolds.\n\n![wefts and warps](http://ryanflorence.com/gifs/warp-weft.gif)\n\n**Loom makes it easy to share best-practices and common patterns for app\ndevelopment.**\n\n- build a set of generators for public consumption based on some\n  framework or library (like ember, angular, backbone, etc.)\n- consume those sets of generators\n- override those generators\n- build your own generators for your specific app\n\nUsing Loom Generator Packages from NPM\n--------------------------------------\n\nUsing generator packages from npm is easy:\n\n```sh\nnpm install loom-generators-ember --save\nnpm install loom-generators-ember-qunit --save\ngenerate controller user name:string age:number\n```\n\nThen refer to the documentation for the generators you've installed.\n\nYou must install with `--save` or add the module to your package.json\ninstead (that's how loom knows how to use them).\n\nIf two generator sets respond to the same commands, they will both be\nrun, allowing authors and consumers to compose them.\n\nCreating Your Own Generators\n----------------------------\n\nAlso, see [the full generator API below](#generator-api)\n\nWhile using generators others have created for you is great, its awesome\nto have a simple way to make generators for our own apps. Even if you're\nusing a set of generators from npm, defining your own generators will\noverride them.\n\n### Installation\n\n```sh\nnpm install loom -g\ngenerate --init\n```\n\n### Templates\n\nInitializing loom simply creates some directories in your project. After\nthat, all you need is a template in `./loom/templates/`:\n\nLets say we have a lot of \"meal\" objects in our app, lets make a\ntemplate for what one of these objects looks like:\n\n_loom/templates/app/meal.js.hbs_\n\n```mustache\nfunction {{objectName}}() {\n  this.food = '{{params.food}}';\n  this.venue = '{{params.venue}}';\n}\n```\n\nAnd then you can generate files based on the template:\n\n```sh\ngenerate app/meal.js lunch food:taco venue:cart\n```\n\nThis will create a file at `app/lunch.js` that looks like:\n\n```js\nfunction lunch() {\n  this.food = 'taco';\n  this.venue = 'cart';\n}\n```\n\nLoom, by default, will save files to your app in the same relative\nlocation they were found in your templates directory.\n\n### Generators\n\nWe can define a generator to make everything a little nicer. First we'll\ncreate a `present` method that determines what data goes to the\ntemplate. Then we'll tell it where to find the template so we can\nsimplify the generator command.\n\n_loom/generators/meal.js_\n\n```js\nexports.present = function(next, env) {\n  var locals = env.params;\n  var name = env.args[0];\n  locals.constructorName = name.charAt(0).toUpperCase() + name.slice(1);\n  return locals;\n};\n\nexports.template = 'app/meal.js.hbs';\n```\n\nNow our template is simpler, no more `{{params.food}}` and it\ncapitalizes our constructor like a proper lady or gent.\n\n_loom/templates/meal.js.hbs_\n\n```mustache\nfunction {{constructorName}}() {\n  this.food = '{{food}}';\n  this.venue = '{{venue}}';\n}\n```\n\nAnd finally our command is simpler, it now just matches a generator\nnamed `meal` instead of a template found at `app/meal.js`.\n\n`generate meal lunch food:taco venue:cart`\n\n### Engines\n\nThe default generator uses handlebars, but we can swap it out for ejs by\ncreating a very simple \"engine\":\n\n_loom/engines/ejs.js_\n\n```js\nvar _ = require('underscore');\n// module.exports = _.template\n// that works, but for clarity:\n\nmodule.exports = function(src, locals, callback) {\n  callback(_.template(src, locals));\n};\n```\n\nRename your template to `meal.js.ejs` and edit it:\n\n```ejs\nfunction <%= constructorName %>() {\n  this.food = '<%= food %>';\n  this.venue = '<%= venue %>';\n}\n```\n\nUpdate your generator to point to the proper template:\n\n```js\nexports.template = 'app/meal.js.ejs';\n```\n\nLoom looks at the file extension of the template (in this case `ejs`)\nand then tries to find a template engine named `ejs.js`.\n\nNow generate your newly configured template:\n\n`generate meal lunch food:taco venue:cart`\n\n### Multiple templates for one generator\n\nIts very common for a generator to create several files, like unit tests\nand scaffoling. Lets add a unit test template to our meal generator.\n\n_loom/templates/test/unit/meal.spec.js.ejs_\n\n```ejs\ndescribe('<%= constructorName %>', function() {\n  it('sets food to \"<%= food %>\"', function() {\n    var meal = new <%= constructorName %>();\n    expect(meal.food).to.equal('<%= food %>');\n  });\n});\n```\n\nAnd add the template path to your generator, note the rename from\n`exports.template` to `export.templates`.\n\n```js\nexports.templates = [\n  'app/meal.js.ejs',\n  'test/unit/meal.spec.js.ejs'\n];\n```\n\nBoth templates will get the same data from `generator.present` and the\nfiles will be saved to the same relative path in your app as they are\ndefined in your templates directory.\n\n### Default Generators\n\nIf you define `loom/generators/default.js`, loom will use it when a\nspecific generator is not found.\n\n\nPublishing Generators to NPM for Everybody\n------------------------------------------\n\nName your module `loom-generators-<name>` (like\n`loom-generators-ember`), place generators, templates, and engines in\n`./loom`, and then publish.  That's it. People can simply `npm install\nloom-generators-<name> --save` and start using them.\n\nPublishing Template Engines to NPM for Everybody\n------------------------------------------------\n\nTo add support for your favorite templating engine you can either add a\nfile to `loom/engines` or publish a module to npm named\n`loom-engine-<ext>`. Loom will attempt to require the engine if it\ndoesn't find it in your project.\n\nGenerator API\n-------------\n\nLoom has a generic generator that can be overridden to meet your specific\nuse case. Generators can export a few methods that loom will use.\n\nYour generator can implement as many methods as you need, loom will\nmerge in the `generic_generator` methods that you don't provide.\n\nHere's a generator that does nothing:\n\n_loom/generators/noop.js_\n\n```js\nexports.before = function(){};\nexports.after = function(){};\nexports.present = function(){};\nexports.savePath = function(){};\nexports.write = function(){};\nexports.render = function(){};\nexports.template = '';\n// exports.template = function(){};\n// exports.templates = [];\n// exports.templates = function(){};\n```\n\nBelow is documentation on generator API, also, check out the [generic\ngenerator](lib/generic_generator).\n\nAll methods share the first two arguments: `next`, and `env`.\n\n- `next` - all methods are asynchronous, so when you're done doing what\n  you need to do, call `next(val)`.\n- `env` - the loom environment, it contains all sorts of information\n  about the `generate` command the user ran.\n\n### generator.before\n\nExecutes before anything else happens. Useful if you need to set or\nchange some things on `env` before it moves through the other methods of\nyour generator.\n\n#### signature\n\n`function(next, env)`\n\n1. next (Function) - the callback.\n2. env (Object) - the loom environment object.\n\n\n### generator.after\n\nExecutes after everything else happens. Useful if you want to give the\nuser some instructions about the files they just generated.\n\n#### signature\n\n`function(next, env)`\n\n1. next (Function) - the callback.\n2. env (Object) - the loom environment object.\n\n\n### generator.present\n\nYou're probably going to want `env.args` and `env.params`.\n\n#### signature\n\n`function(next, env)`\n\n#### arguments\n\n1. next (Function) - the callback.\n2. env (Object) - the loom environment object.\n\n#### examples\n\nLets make a generator that logs the arguments to explore how this works.\n\n_loom/generators/user.js_\n\n```js\nexports.present = function(next, env) {\n  console.log(env);\n};\n```\n\nThe following are commands followed by what is logged for the arguments:\n\n```sh\ngenerate model user name:string age:number\n{ args: ['user'], params: { name: 'string', age: 'number' } }\n\ngenerate model foo bar baz qux:1 quux:2\n{ args: ['foo', 'bar', 'baz' ]\n  params: { qux: '1', quux: '2' } }\n```\n\nAs you can see, the space separated values become the `args` and the\nkey:value pairs are wrapped up into the `params` argument.\n\n\n### generator.template\n\nDetermines which template to render.\n\n`exports.template` can simply be a string, or a function if you need to\ncompute it.\n\nPaths are relative to the `./loom/templates` directory.\n\n#### example\n\nTo use a template found at\n`loom/templates/spec/models/model.spec.js.hbs`:\n\n```js\nexports.template = 'spec/models/model.spec.js.hbs';\nexports.template = function(next) {\n  // some computation\n  next('spec/models/model.spec.js.hbs');\n};\n```\n\n#### notes\n\nUnless you override `generator.write` the generated file will be saved\nin the mirrored location in `loom/templates`, so the example above will\nbe saved to `spec/models/<name>.spec.js`.\n\n### generator.templates\n\nSame as `template` but is an array of template paths that take\nprecendence over `template`. Each template will receive the same locals\nreturned from `present`. Can also be a function that calls back an array.\n\n#### examples\n\n```js\nexports.templates = [\n  'app/models/model.js.ejs',\n  'spec/models/model.spec.js.ejs'\n];\n\nexports.templates = function(next) {\n  next([\n    'app/models/model.js.ejs',\n    'spec/models/model.spec.js.ejs'\n  ]);\n};\n```\n\n### generator.savePath\n\nDetermines the path in which to save a template.\n\n#### signature\n\n`function(next, env, template)`\n\n#### arguments\n\n1. next (Function) - callback with the savePath you want\n2. env (Object) - the loom environment object\n3. template (String) - the path of the template being rendered\n\n### generator.write\n\nWrites a rendered template to the file system, its unlikely you'll want\nto override this.\n\n#### signature\n\n`function(next, env, savePath, src)`\n\n### generator.render\n\nDetermines how to render the template, its unlinkely you'll want to\noverride this.\n\n#### signature\n\n`function(next, env, engine, templatePath, locals)`\n\nTODO\n----\n\n- conflict resolution when two generators want to save to the same path\n- --force option to overwrite files (better for scripting so you don't\n  get the prompt)\n\nLicense and Copyright\n---------------------\n\nMIT Style license\n\n(c) 2013 Ryan Florence\n\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/rpflorence/loom/issues"},"homepage":"https://github.com/rpflorence/loom","_id":"loom@3.0.3","dist":{"shasum":"0d5923a617e9f1530493bf2edb1f69a3ce44b831","tarball":"https://registry.npmjs.org/loom/-/loom-3.0.3.tgz","integrity":"sha512-lBg5ulpuh7utXgDt2h/h8lOE5iwKTx5ZKQ1rPxgHtWn7V/ZyDIdaFvaaFUfPKlq5TQ/d8UVGhCYuG14qwFIOYA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDj9EYRCWKsBs7mWb9a2xamazdcV7E5VC5d7H1WliW6gAIhAP6L6xwvoWQl0aQT6+GGeRjnr/kXrn4/OLCDoC/32RvQ"}]},"_from":".","_npmVersion":"1.3.14","_npmUser":{"name":"ryanflorence","email":"rpflorence@gmail.com"},"maintainers":[{"name":"ryanflorence","email":"rpflorence+npm@gmail.com"}]},"3.1.1":{"name":"loom","version":"3.1.1","description":"Weave your wefts betwixt the warps of loom generators and scaffolds.","main":"loom.js","scripts":{"test":"node_modules/.bin/mocha --require should --reporter dot --ui bdd $(find test -name \"*.spec.js\")","watch":"node_modules/.bin/mocha --watch --require should --reporter dot --ui bdd $(find test -name \"*.spec.js\")"},"bin":{"generate":"./bin/generate"},"author":{"name":"Ryan Florence"},"license":"MIT","peerDependencies":{"originate":"0.1.0"},"dependencies":{"commander":"~2.0.0","fs-extra":"~0.6.3","loom-engine-hbs":"2.0.0","cli-color":"~0.2.2","cli-prompt":"~0.3.2","async":"~0.2.9"},"devDependencies":{"mocha":"~1.12.0","sinon":"~1.7.3","should":"~1.2.2"},"repository":{"type":"git","url":"git://github.com/rpflorence/loom"},"keywords":["generator","scaffold","template","templating"],"readme":"Loom\n====\n\nWeave your wefts betwixt the warps of loom generators and scaffolds.\n\n![wefts and warps](http://ryanflorence.com/gifs/warp-weft.gif)\n\n**Loom makes it easy to share best-practices and common patterns for app\ndevelopment.**\n\n- build a set of generators for public consumption based on some\n  framework or library (like ember, angular, backbone, etc.)\n- consume those sets of generators\n- override those generators\n- build your own generators for your specific app\n\nUsing Loom Generator Packages from npm\n--------------------------------------\n\nUsing generator packages from npm is easy:\n\n```sh\nnpm install loom-ember --save\nnpm install loom-ember-qunit --save\ngenerate controller user name:string age:number\n```\n\nThen refer to the documentation for the generators you've installed.\n\nYou must install with `--save` or add the module to your package.json\ninstead (that's how loom knows how to use them).\n\nIf two generator sets respond to the same commands, they will both be\nrun, allowing authors and consumers to compose them.\n\nCreate New Project Scaffolds with `originate`\n---------------------------------------------\n\nIn addition to generator sets, full project scaffolds are a simple\ncommand away when an author publishes a project to npm with a name\nmatching `originate-*`.\n\nFor example:\n\n```sh\nnpm install -g loom\noriginate ember my-new-app\n```\n\nRead more about [originate][1].\n\nCreating Your Own Generators\n----------------------------\n\nAlso, see [the full generator API below](#generator-api)\n\nWhile using generators others have created for you is great, its awesome\nto have a simple way to make generators for our own apps. Even if you're\nusing a set of generators from npm, defining your own generators will\noverride them.\n\n### Installation\n\n```sh\nnpm install loom -g\ngenerate --init\n```\n\n### Templates\n\nInitializing loom simply creates some directories in your project. After\nthat, all you need is a template in `./loom/templates/`:\n\nLets say we have a lot of \"meal\" objects in our app, lets make a\ntemplate for what one of these objects looks like:\n\n_loom/templates/app/meal.js.hbs_\n\n```mustache\nfunction {{objectName}}() {\n  this.food = '{{params.food}}';\n  this.venue = '{{params.venue}}';\n}\n```\n\nAnd then you can generate files based on the template:\n\n```sh\ngenerate app/meal.js lunch food:taco venue:cart\n```\n\nThis will create a file at `app/lunch.js` that looks like:\n\n```js\nfunction lunch() {\n  this.food = 'taco';\n  this.venue = 'cart';\n}\n```\n\nLoom, by default, will save files to your app in the same relative\nlocation they were found in your templates directory.\n\n### Generators\n\nWe can define a generator to make everything a little nicer. First we'll\ncreate a `present` method that determines what data goes to the\ntemplate. Then we'll tell it where to find the template so we can\nsimplify the generator command.\n\n_loom/generators/meal.js_\n\n```js\nexports.present = function(next, env) {\n  var locals = env.params;\n  var name = env.args[0];\n  locals.constructorName = name.charAt(0).toUpperCase() + name.slice(1);\n  return locals;\n};\n\nexports.template = 'app/meal.js.hbs';\n```\n\nNow our template is simpler, no more `{{params.food}}` and it\ncapitalizes our constructor like a proper lady or gent.\n\n_loom/templates/meal.js.hbs_\n\n```mustache\nfunction {{constructorName}}() {\n  this.food = '{{food}}';\n  this.venue = '{{venue}}';\n}\n```\n\nAnd finally our command is simpler, it now just matches a generator\nnamed `meal` instead of a template found at `app/meal.js`.\n\n`generate meal lunch food:taco venue:cart`\n\n### Engines\n\nThe default generator uses handlebars, but we can swap it out for ejs by\ncreating a very simple \"engine\":\n\n_loom/engines/ejs.js_\n\n```js\nvar _ = require('underscore');\n// module.exports = _.template\n// that works, but for clarity:\n\nmodule.exports = function(src, locals, callback) {\n  callback(_.template(src, locals));\n};\n```\n\nRename your template to `meal.js.ejs` and edit it:\n\n```ejs\nfunction <%= constructorName %>() {\n  this.food = '<%= food %>';\n  this.venue = '<%= venue %>';\n}\n```\n\nUpdate your generator to point to the proper template:\n\n```js\nexports.template = 'app/meal.js.ejs';\n```\n\nLoom looks at the file extension of the template (in this case `ejs`)\nand then tries to find a template engine named `ejs.js`.\n\nNow generate your newly configured template:\n\n`generate meal lunch food:taco venue:cart`\n\n### Multiple templates for one generator\n\nIts very common for a generator to create several files, like unit tests\nand scaffoling. Lets add a unit test template to our meal generator.\n\n_loom/templates/test/unit/meal.spec.js.ejs_\n\n```ejs\ndescribe('<%= constructorName %>', function() {\n  it('sets food to \"<%= food %>\"', function() {\n    var meal = new <%= constructorName %>();\n    expect(meal.food).to.equal('<%= food %>');\n  });\n});\n```\n\nAnd add the template path to your generator, note the rename from\n`exports.template` to `export.templates`.\n\n```js\nexports.templates = [\n  'app/meal.js.ejs',\n  'test/unit/meal.spec.js.ejs'\n];\n```\n\nBoth templates will get the same data from `generator.present` and the\nfiles will be saved to the same relative path in your app as they are\ndefined in your templates directory.\n\n### Default Generators\n\nIf you define `loom/generators/default.js`, loom will use it when a\nspecific generator is not found.\n\n\nPublishing Generators to npm for Everybody\n------------------------------------------\n\nName your module `loom-<name>` (like\n`loom-ember`), place generators, templates, and engines in\n`./loom`, and then publish.  That's it. People can simply `npm install\nloom-<name> --save` and start using them.\n\nPublishing Template Engines to npm for Everybody\n------------------------------------------------\n\nTo add support for your favorite templating engine you can either add a\nfile to `loom/engines` or publish a module to npm named\n`loom-engine-<ext>`. Loom will attempt to require the engine if it\ndoesn't find it in your project.\n\nGenerator API\n-------------\n\nLoom has a generic generator that can be overridden to meet your specific\nuse case. Generators can export a few methods that loom will use.\n\nYour generator can implement as many methods as you need, loom will\nmerge in the `generic_generator` methods that you don't provide.\n\nHere's a generator that does nothing:\n\n_loom/generators/noop.js_\n\n```js\nexports.before = function(){};\nexports.present = function(){};\nexports.savePath = function(){};\nexports.write = function(){};\nexports.render = function(){};\nexports.template = '';\n// exports.template = function(){};\n// exports.templates = [];\n// exports.templates = function(){};\n```\n\nBelow is documentation on generator API, also, check out the [generic\ngenerator](lib/generic_generator).\n\nAll methods share the first two arguments: `next`, and `env`.\n\n- `next` - all methods are asynchronous, so when you're done doing what\n  you need to do, call `next(val)`.\n- `env` - the loom environment, it contains all sorts of information\n  about the `generate` command the user ran.\n\n### generator.before\n\nExecutes before anything else happens. Useful if you need to set or\nchange some things on `env` before it moves through the other methods of\nyour generator.\n\n#### signature\n\n`function(next, env)`\n\n\n1. next (Function) - the callback.\n2. env (Object) - the loom environment object.\n\n\n### generator.present\n\nYou're probably going to want `env.args` and `env.params`.\n\n#### signature\n\n`function(next, env)`\n\n#### arguments\n\n1. next (Function) - the callback.\n2. env (Object) - the loom environment object.\n\n#### examples\n\nLets make a generator that logs the arguments to explore how this works.\n\n_loom/generators/user.js_\n\n```js\nexports.present = function(next, env) {\n  console.log(env);\n};\n```\n\nThe following are commands followed by what is logged for the arguments:\n\n```sh\ngenerate model user name:string age:number\n{ args: ['user'], params: { name: 'string', age: 'number' } }\n\ngenerate model foo bar baz qux:1 quux:2\n{ args: ['foo', 'bar', 'baz' ]\n  params: { qux: '1', quux: '2' } }\n```\n\nAs you can see, the space separated values become the `args` and the\nkey:value pairs are wrapped up into the `params` argument.\n\n\n### generator.template\n\nDetermines which template to render.\n\n`exports.template` can simply be a string, or a function if you need to\ncompute it.\n\nPaths are relative to the `./loom/templates` directory.\n\n#### example\n\nTo use a template found at\n`loom/templates/spec/models/model.spec.js.hbs`:\n\n```js\nexports.template = 'spec/models/model.spec.js.hbs';\nexports.template = function(next) {\n  // some computation\n  next('spec/models/model.spec.js.hbs');\n};\n```\n\n#### notes\n\nUnless you override `generator.write` the generated file will be saved\nin the mirrored location in `loom/templates`, so the example above will\nbe saved to `spec/models/<name>.spec.js`.\n\n### generator.templates\n\nSame as `template` but is an array of template paths that take\nprecendence over `template`. Each template will receive the same locals\nreturned from `present`. Can also be a function that calls back an array.\n\n#### examples\n\n```js\nexports.templates = [\n  'app/models/model.js.ejs',\n  'spec/models/model.spec.js.ejs'\n];\n\nexports.templates = function(next) {\n  next([\n    'app/models/model.js.ejs',\n    'spec/models/model.spec.js.ejs'\n  ]);\n};\n```\n\n### generator.savePath\n\nDetermines the path in which to save a template.\n\n#### signature\n\n`function(next, env, template)`\n\n#### arguments\n\n1. next (Function) - callback with the savePath you want\n2. env (Object) - the loom environment object\n3. template (String) - the path of the template being rendered\n\n### generator.write\n\nWrites a rendered template to the file system, its unlikely you'll want\nto override this.\n\n#### signature\n\n`function(next, env, savePath, src)`\n\n### generator.render\n\nDetermines how to render the template, its unlinkely you'll want to\noverride this.\n\n#### signature\n\n`function(next, env, engine, templatePath, locals)`\n\nTODO\n----\n\n- conflict resolution when two generators want to save to the same path\n- --force option to overwrite files (better for scripting so you don't\n  get the prompt)\n\nLicense and Copyright\n---------------------\n\nMIT Style license\n\n(c) 2013 Ryan Florence\n\n  [1]:https://github.com/rpflorence/originate\n\n\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/rpflorence/loom/issues"},"homepage":"https://github.com/rpflorence/loom","_id":"loom@3.1.1","dist":{"shasum":"f643a6bbca7375b860b80ec5075f0b645d363562","tarball":"https://registry.npmjs.org/loom/-/loom-3.1.1.tgz","integrity":"sha512-n+q5xQE2Q0LfeVYBtHqQ9T5J7BooosHAgmVY3kVrqZLZcHrjcTGiEbGA0NznGlNcuAfhiDK0cOYCgESloqlWvw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAyRrM622LlqNJ3cFu/iOZ0HaDN/EfF3aAF4LX9DE/egAiEAqcS9zVrZDe1ZeZpjLnwUcWZf/L0o2GgGl3BJgMVrBNw="}]},"_from":".","_npmVersion":"1.3.14","_npmUser":{"name":"ryanflorence","email":"rpflorence@gmail.com"},"maintainers":[{"name":"ryanflorence","email":"rpflorence+npm@gmail.com"}]},"3.1.2":{"name":"loom","version":"3.1.2","description":"Weave your wefts betwixt the warps of loom generators and scaffolds.","main":"loom.js","scripts":{"test":"node_modules/.bin/mocha --require should --reporter dot --ui bdd $(find test -name \"*.spec.js\")","watch":"node_modules/.bin/mocha --watch --require should --reporter dot --ui bdd $(find test -name \"*.spec.js\")"},"bin":{"generate":"./bin/generate"},"author":{"name":"Ryan Florence"},"license":"MIT","peerDependencies":{"originate":"0.1.x"},"dependencies":{"commander":"~2.0.0","fs-extra":"~0.6.3","loom-engine-hbs":"2.0.0","cli-color":"~0.2.2","cli-prompt":"~0.3.2","async":"~0.2.9"},"devDependencies":{"mocha":"~1.12.0","sinon":"~1.7.3","should":"~1.2.2"},"repository":{"type":"git","url":"git://github.com/rpflorence/loom"},"keywords":["generator","scaffold","template","templating"],"readme":"Loom\n====\n\nWeave your wefts betwixt the warps of loom generators and scaffolds.\n\n![wefts and warps](http://ryanflorence.com/gifs/warp-weft.gif)\n\n**Loom makes it easy to share best-practices and common patterns for app\ndevelopment.**\n\n- build a set of generators for public consumption based on some\n  framework or library (like ember, angular, backbone, etc.)\n- consume those sets of generators\n- override those generators\n- build your own generators for your specific app\n\nUsing Loom Generator Packages from npm\n--------------------------------------\n\nUsing generator packages from npm is easy:\n\n```sh\nnpm install loom-ember --save\nnpm install loom-ember-qunit --save\ngenerate controller user name:string age:number\n```\n\nThen refer to the documentation for the generators you've installed.\n\nYou must install with `--save` or add the module to your package.json\ninstead (that's how loom knows how to use them).\n\nIf two generator sets respond to the same commands, they will both be\nrun, allowing authors and consumers to compose them.\n\nCreate New Project Scaffolds with `originate`\n---------------------------------------------\n\nIn addition to generator sets, full project scaffolds are a simple\ncommand away when an author publishes a project to npm with a name\nmatching `originate-*`.\n\nFor example:\n\n```sh\nnpm install -g loom\noriginate ember my-new-app\n```\n\nRead more about [originate][1].\n\nCreating Your Own Generators\n----------------------------\n\nAlso, see [the full generator API below](#generator-api)\n\nWhile using generators others have created for you is great, its awesome\nto have a simple way to make generators for our own apps. Even if you're\nusing a set of generators from npm, defining your own generators will\noverride them.\n\n### Installation\n\n```sh\nnpm install loom -g\ngenerate --init\n```\n\n### Templates\n\nInitializing loom simply creates some directories in your project. After\nthat, all you need is a template in `./loom/templates/`:\n\nLets say we have a lot of \"meal\" objects in our app, lets make a\ntemplate for what one of these objects looks like:\n\n_loom/templates/app/meal.js.hbs_\n\n```mustache\nfunction {{objectName}}() {\n  this.food = '{{params.food}}';\n  this.venue = '{{params.venue}}';\n}\n```\n\nAnd then you can generate files based on the template:\n\n```sh\ngenerate app/meal.js lunch food:taco venue:cart\n```\n\nThis will create a file at `app/lunch.js` that looks like:\n\n```js\nfunction lunch() {\n  this.food = 'taco';\n  this.venue = 'cart';\n}\n```\n\nLoom, by default, will save files to your app in the same relative\nlocation they were found in your templates directory.\n\n### Generators\n\nWe can define a generator to make everything a little nicer. First we'll\ncreate a `present` method that determines what data goes to the\ntemplate. Then we'll tell it where to find the template so we can\nsimplify the generator command.\n\n_loom/generators/meal.js_\n\n```js\nexports.present = function(next, env) {\n  var locals = env.params;\n  var name = env.args[0];\n  locals.constructorName = name.charAt(0).toUpperCase() + name.slice(1);\n  return locals;\n};\n\nexports.template = 'app/meal.js.hbs';\n```\n\nNow our template is simpler, no more `{{params.food}}` and it\ncapitalizes our constructor like a proper lady or gent.\n\n_loom/templates/meal.js.hbs_\n\n```mustache\nfunction {{constructorName}}() {\n  this.food = '{{food}}';\n  this.venue = '{{venue}}';\n}\n```\n\nAnd finally our command is simpler, it now just matches a generator\nnamed `meal` instead of a template found at `app/meal.js`.\n\n`generate meal lunch food:taco venue:cart`\n\n### Engines\n\nThe default generator uses handlebars, but we can swap it out for ejs by\ncreating a very simple \"engine\":\n\n_loom/engines/ejs.js_\n\n```js\nvar _ = require('underscore');\n// module.exports = _.template\n// that works, but for clarity:\n\nmodule.exports = function(src, locals, callback) {\n  callback(_.template(src, locals));\n};\n```\n\nRename your template to `meal.js.ejs` and edit it:\n\n```ejs\nfunction <%= constructorName %>() {\n  this.food = '<%= food %>';\n  this.venue = '<%= venue %>';\n}\n```\n\nUpdate your generator to point to the proper template:\n\n```js\nexports.template = 'app/meal.js.ejs';\n```\n\nLoom looks at the file extension of the template (in this case `ejs`)\nand then tries to find a template engine named `ejs.js`.\n\nNow generate your newly configured template:\n\n`generate meal lunch food:taco venue:cart`\n\n### Multiple templates for one generator\n\nIts very common for a generator to create several files, like unit tests\nand scaffoling. Lets add a unit test template to our meal generator.\n\n_loom/templates/test/unit/meal.spec.js.ejs_\n\n```ejs\ndescribe('<%= constructorName %>', function() {\n  it('sets food to \"<%= food %>\"', function() {\n    var meal = new <%= constructorName %>();\n    expect(meal.food).to.equal('<%= food %>');\n  });\n});\n```\n\nAnd add the template path to your generator, note the rename from\n`exports.template` to `export.templates`.\n\n```js\nexports.templates = [\n  'app/meal.js.ejs',\n  'test/unit/meal.spec.js.ejs'\n];\n```\n\nBoth templates will get the same data from `generator.present` and the\nfiles will be saved to the same relative path in your app as they are\ndefined in your templates directory.\n\n### Default Generators\n\nIf you define `loom/generators/default.js`, loom will use it when a\nspecific generator is not found.\n\n\nPublishing Generators to npm for Everybody\n------------------------------------------\n\nName your module `loom-<name>` (like\n`loom-ember`), place generators, templates, and engines in\n`./loom`, and then publish.  That's it. People can simply `npm install\nloom-<name> --save` and start using them.\n\nPublishing Template Engines to npm for Everybody\n------------------------------------------------\n\nTo add support for your favorite templating engine you can either add a\nfile to `loom/engines` or publish a module to npm named\n`loom-engine-<ext>`. Loom will attempt to require the engine if it\ndoesn't find it in your project.\n\nGenerator API\n-------------\n\nLoom has a generic generator that can be overridden to meet your specific\nuse case. Generators can export a few methods that loom will use.\n\nYour generator can implement as many methods as you need, loom will\nmerge in the `generic_generator` methods that you don't provide.\n\nHere's a generator that does nothing:\n\n_loom/generators/noop.js_\n\n```js\nexports.before = function(){};\nexports.present = function(){};\nexports.savePath = function(){};\nexports.write = function(){};\nexports.render = function(){};\nexports.template = '';\n// exports.template = function(){};\n// exports.templates = [];\n// exports.templates = function(){};\n```\n\nBelow is documentation on generator API, also, check out the [generic\ngenerator](lib/generic_generator).\n\nAll methods share the first two arguments: `next`, and `env`.\n\n- `next` - all methods are asynchronous, so when you're done doing what\n  you need to do, call `next(val)`.\n- `env` - the loom environment, it contains all sorts of information\n  about the `generate` command the user ran.\n\n### generator.before\n\nExecutes before anything else happens. Useful if you need to set or\nchange some things on `env` before it moves through the other methods of\nyour generator.\n\n#### signature\n\n`function(next, env)`\n\n\n1. next (Function) - the callback.\n2. env (Object) - the loom environment object.\n\n\n### generator.present\n\nYou're probably going to want `env.args` and `env.params`.\n\n#### signature\n\n`function(next, env)`\n\n#### arguments\n\n1. next (Function) - the callback.\n2. env (Object) - the loom environment object.\n\n#### examples\n\nLets make a generator that logs the arguments to explore how this works.\n\n_loom/generators/user.js_\n\n```js\nexports.present = function(next, env) {\n  console.log(env);\n};\n```\n\nThe following are commands followed by what is logged for the arguments:\n\n```sh\ngenerate model user name:string age:number\n{ args: ['user'], params: { name: 'string', age: 'number' } }\n\ngenerate model foo bar baz qux:1 quux:2\n{ args: ['foo', 'bar', 'baz' ]\n  params: { qux: '1', quux: '2' } }\n```\n\nAs you can see, the space separated values become the `args` and the\nkey:value pairs are wrapped up into the `params` argument.\n\n\n### generator.template\n\nDetermines which template to render.\n\n`exports.template` can simply be a string, or a function if you need to\ncompute it.\n\nPaths are relative to the `./loom/templates` directory.\n\n#### example\n\nTo use a template found at\n`loom/templates/spec/models/model.spec.js.hbs`:\n\n```js\nexports.template = 'spec/models/model.spec.js.hbs';\nexports.template = function(next) {\n  // some computation\n  next('spec/models/model.spec.js.hbs');\n};\n```\n\n#### notes\n\nUnless you override `generator.write` the generated file will be saved\nin the mirrored location in `loom/templates`, so the example above will\nbe saved to `spec/models/<name>.spec.js`.\n\n### generator.templates\n\nSame as `template` but is an array of template paths that take\nprecendence over `template`. Each template will receive the same locals\nreturned from `present`. Can also be a function that calls back an array.\n\n#### examples\n\n```js\nexports.templates = [\n  'app/models/model.js.ejs',\n  'spec/models/model.spec.js.ejs'\n];\n\nexports.templates = function(next) {\n  next([\n    'app/models/model.js.ejs',\n    'spec/models/model.spec.js.ejs'\n  ]);\n};\n```\n\n### generator.savePath\n\nDetermines the path in which to save a template.\n\n#### signature\n\n`function(next, env, template)`\n\n#### arguments\n\n1. next (Function) - callback with the savePath you want\n2. env (Object) - the loom environment object\n3. template (String) - the path of the template being rendered\n\n### generator.write\n\nWrites a rendered template to the file system, its unlikely you'll want\nto override this.\n\n#### signature\n\n`function(next, env, savePath, src)`\n\n### generator.render\n\nDetermines how to render the template, its unlinkely you'll want to\noverride this.\n\n#### signature\n\n`function(next, env, engine, templatePath, locals)`\n\nTODO\n----\n\n- conflict resolution when two generators want to save to the same path\n- --force option to overwrite files (better for scripting so you don't\n  get the prompt)\n\nLicense and Copyright\n---------------------\n\nMIT Style license\n\n(c) 2013 Ryan Florence\n\n  [1]:https://github.com/rpflorence/originate\n\n\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/rpflorence/loom/issues"},"homepage":"https://github.com/rpflorence/loom","_id":"loom@3.1.2","dist":{"shasum":"140d8b29f00c41f424b106256319b1737efe1685","tarball":"https://registry.npmjs.org/loom/-/loom-3.1.2.tgz","integrity":"sha512-C+KbC6+x+7evvUdTWIUa3Aq6sjt5MPWQ8XsWp4yUYV5VcKiSnC69ThIcDBzUsX4lAg9IwReHzdlHoTya05A7og==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD3vO/ZqSaIewoLx9Qd29IaZvf6HXs32/iyWgYWAMKYJQIhANBikpDVhe1R+2hQ40BOfSYZCxle8hmO5P8rb/KrjYee"}]},"_from":".","_npmVersion":"1.3.14","_npmUser":{"name":"ryanflorence","email":"rpflorence@gmail.com"},"maintainers":[{"name":"ryanflorence","email":"rpflorence+npm@gmail.com"}]}},"maintainers":[{"name":"ryanflorence","email":"rpflorence+npm@gmail.com"}],"time":{"modified":"2022-06-19T14:07:59.287Z","created":"2011-05-05T14:11:11.461Z","1.0.0":"2011-05-05T14:11:11.946Z","2.0.0":"2013-11-17T07:09:43.418Z","2.0.0-beta.1":"2013-11-17T07:06:43.737Z","3.0.0-beta.1":"2013-11-17T07:09:55.027Z","3.0.0-beta.2":"2013-11-18T05:46:10.453Z","3.0.0-beta.3":"2013-11-29T06:45:08.913Z","3.0.0":"2013-11-30T06:58:56.487Z","3.0.1":"2013-11-30T19:25:53.117Z","3.0.2":"2013-11-30T20:00:14.796Z","3.0.3":"2013-12-02T04:59:50.841Z","3.1.1":"2013-12-02T06:26:12.971Z","3.1.2":"2013-12-02T06:40:35.985Z"},"repository":{"type":"git","url":"git://github.com/rpflorence/loom"},"author":{"name":"Ryan Florence"}}