├── fixtures ├── a.txt ├── b.txt ├── c.txt ├── a.hbs ├── b.hbs └── c.hbs ├── .gitattributes ├── .travis.yml ├── .gitignore ├── .editorconfig ├── verbfile.js ├── assemblefile.js ├── LICENSE ├── .verb.md ├── package.json ├── README.md ├── .eslintrc.json ├── test.js └── index.js /fixtures/a.txt: -------------------------------------------------------------------------------- 1 | This is AAA! -------------------------------------------------------------------------------- /fixtures/b.txt: -------------------------------------------------------------------------------- 1 | This is BBB! -------------------------------------------------------------------------------- /fixtures/c.txt: -------------------------------------------------------------------------------- 1 | This is CCC! -------------------------------------------------------------------------------- /fixtures/a.hbs: -------------------------------------------------------------------------------- 1 | This is {{name}}! -------------------------------------------------------------------------------- /fixtures/b.hbs: -------------------------------------------------------------------------------- 1 | This is {{name}}! -------------------------------------------------------------------------------- /fixtures/c.hbs: -------------------------------------------------------------------------------- 1 | This is {{name}}! -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Enforce Unix newlines 2 | * text eol=lf 3 | 4 | # binaries 5 | *.ai binary 6 | *.psd binary 7 | *.jpg binary 8 | *.gif binary 9 | *.png binary 10 | *.jpeg binary 11 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - stable 5 | - '5' 6 | - '4' 7 | - '0.12' 8 | - '0.10' 9 | matrix: 10 | fast_finish: true 11 | allow_failures: 12 | - node_js: '0.10' 13 | - node_js: '0.12' 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # always ignore files 2 | *.DS_Store 3 | *.sublime-* 4 | 5 | # test related, or directories generated by tests 6 | test/actual 7 | actual 8 | coverage 9 | 10 | # npm 11 | node_modules 12 | npm-debug.log 13 | 14 | # misc 15 | _gh_pages 16 | benchmark 17 | bower_components 18 | vendor 19 | temp 20 | tmp 21 | TODO.md 22 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | end_of_line = lf 7 | charset = utf-8 8 | indent_size = 2 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | insert_final_newline = false 15 | 16 | [**/{actual,fixtures,expected}/**] 17 | trim_trailing_whitespace = false 18 | insert_final_newline = false 19 | 20 | [**/templates/**] 21 | trim_trailing_whitespace = false 22 | insert_final_newline = false 23 | -------------------------------------------------------------------------------- /verbfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var path = require('path'); 4 | var cwd = path.join.bind(path, __dirname, 'test/fixtures'); 5 | var select = require('./'); 6 | 7 | /** 8 | * Example usage with verb 9 | * 10 | * ```sh 11 | * $ verb hbs 12 | * # or 13 | * $ verb txt 14 | * ``` 15 | */ 16 | 17 | module.exports = function(verb) { 18 | verb.use(require('verb-readme-generator')); 19 | verb.use(select()); 20 | 21 | verb.docs.option('renameKey', function(key) { 22 | return path.basename(key); 23 | }); 24 | 25 | verb.task('txt', function(cb) { 26 | verb.docs('fixtures/*.txt'); 27 | verb.selectViews('docs', cb); 28 | }); 29 | 30 | verb.task('hbs', function(cb) { 31 | verb.engine('hbs', require('engine-handlebars')); 32 | verb.option('engine', 'hbs'); 33 | verb.docs('fixtures/*.hbs'); 34 | verb.selectViews('docs', cb); 35 | }); 36 | 37 | verb.task('default', ['readme']); 38 | }; 39 | -------------------------------------------------------------------------------- /assemblefile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var path = require('path'); 4 | var assemble = require('assemble'); 5 | var questions = require('base-questions'); 6 | var conflicts = require('base-fs-conflicts'); 7 | var rename = require('base-fs-rename'); 8 | var select = require('./'); 9 | 10 | // register plugins 11 | var app = assemble() 12 | .use(questions()) 13 | .use(conflicts()) 14 | .use(rename()) 15 | .use(select()) 16 | 17 | app.create('pages'); 18 | app.pages.preRender(/./, function(file, next) { 19 | file.data.name = file.stem.toUpperCase(); 20 | next(); 21 | }); 22 | 23 | // engine 24 | app.engine('hbs', require('engine-handlebars')); 25 | 26 | // options 27 | app.option('engine', 'hbs'); 28 | app.option('flatten', true); 29 | app.option('renameKey', function(key) { 30 | return path.basename(key); 31 | }); 32 | 33 | // example task 34 | app.task('default', function(cb) { 35 | app.pages('fixtures/*.hbs'); 36 | app.selectViews('pages', cb); 37 | }); 38 | 39 | module.exports = app; 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016, Jon Schlinkert. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /.verb.md: -------------------------------------------------------------------------------- 1 | **Example** 2 | 3 | ![assemble-select-views](https://cloud.githubusercontent.com/assets/383994/15114173/af5319de-15c6-11e6-8b66-1ff7bcee8ec7.gif) 4 | 5 | ## Usage 6 | 7 | ```js 8 | var select = require('{%= name %}'); 9 | var assemble = require('assemble'); 10 | var app = assemble(); 11 | 12 | // register the plugin 13 | app.use(select()); 14 | ``` 15 | 16 | **Example usage** 17 | 18 | See [assemblefile.js](assemblefile.js) for a working example. 19 | 20 | ```js 21 | // create a collection 22 | app.create('pages'); 23 | 24 | // add "pages" to the collection 25 | app.page('a.hbs', {content: 'this is {{name}}', data: {name: 'Foo'}}); 26 | app.page('b.hbs', {content: 'this is {{name}}', data: {name: 'Bar'}}); 27 | app.page('c.hbs', {content: 'this is {{name}}', data: {name: 'Baz'}}); 28 | 29 | // register an engine for rendering ".hbs" files 30 | app.engine('hbs', require('engine-handlebars')); 31 | 32 | // ask the user which "pages" they want to render 33 | // and write to the file system 34 | app.selectViews('pages', function(err, views) { 35 | if (err) { 36 | console.log(err); 37 | return; 38 | } 39 | console.log('done!'); 40 | }); 41 | ``` 42 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "assemble-select-views", 3 | "description": "Assemble plugin that adds a `.selectViews` method to the instance, for prompting the user to select the views they want to write to the file system.", 4 | "version": "0.1.5", 5 | "homepage": "https://github.com/assemble/assemble-select-views", 6 | "author": "Jon Schlinkert (https://github.com/jonschlinkert)", 7 | "repository": "assemble/assemble-select-views", 8 | "bugs": { 9 | "url": "https://github.com/assemble/assemble-select-views/issues" 10 | }, 11 | "license": "MIT", 12 | "files": [ 13 | "index.js" 14 | ], 15 | "main": "index.js", 16 | "engines": { 17 | "node": ">=0.10.0" 18 | }, 19 | "scripts": { 20 | "test": "mocha" 21 | }, 22 | "dependencies": { 23 | "base-cwd": "^0.1.6", 24 | "base-questions": "^0.6.0", 25 | "extend-shallow": "^2.0.1" 26 | }, 27 | "devDependencies": { 28 | "assemble": "^0.11.0", 29 | "assemble-core": "^0.17.1", 30 | "base-fs-conflicts": "^0.1.6", 31 | "base-fs-rename": "^0.1.2", 32 | "delete": "^0.3.2", 33 | "engine-handlebars": "^0.8.0", 34 | "fs-exists-sync": "^0.1.0", 35 | "gulp-format-md": "^0.1.9", 36 | "mocha": "^2.4.5", 37 | "verb-readme-generator": "^0.1.11" 38 | }, 39 | "keywords": [ 40 | "assemble", 41 | "choose", 42 | "files" 43 | ], 44 | "verb": { 45 | "toc": false, 46 | "layout": "default", 47 | "tasks": [ 48 | "readme" 49 | ], 50 | "plugins": [ 51 | "gulp-format-md" 52 | ], 53 | "related": { 54 | "list": [ 55 | "assemble", 56 | "assemble-fs", 57 | "base-questions", 58 | "base" 59 | ] 60 | }, 61 | "reflinks": [ 62 | "verb" 63 | ], 64 | "lint": { 65 | "reflinks": true 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # assemble-select-views [![NPM version](https://img.shields.io/npm/v/assemble-select-views.svg?style=flat)](https://www.npmjs.com/package/assemble-select-views) [![NPM downloads](https://img.shields.io/npm/dm/assemble-select-views.svg?style=flat)](https://npmjs.org/package/assemble-select-views) [![Build Status](https://img.shields.io/travis/assemble/assemble-select-views.svg?style=flat)](https://travis-ci.org/assemble/assemble-select-views) 2 | 3 | Assemble plugin that adds a `.selectViews` method to the instance, for prompting the user to select the views they want to write to the file system. 4 | 5 | ## Install 6 | 7 | Install with [npm](https://www.npmjs.com/): 8 | 9 | ```sh 10 | $ npm install assemble-select-views --save 11 | ``` 12 | 13 | **Example** 14 | 15 | ![assemble-select-views](https://cloud.githubusercontent.com/assets/383994/15114173/af5319de-15c6-11e6-8b66-1ff7bcee8ec7.gif) 16 | 17 | ## Usage 18 | 19 | ```js 20 | var select = require('assemble-select-views'); 21 | var assemble = require('assemble'); 22 | var app = assemble(); 23 | 24 | // register the plugin 25 | app.use(select()); 26 | ``` 27 | 28 | **Example usage** 29 | 30 | See [assemblefile.js](assemblefile.js) for a working example. 31 | 32 | ```js 33 | // create a collection 34 | app.create('pages'); 35 | 36 | // add "pages" to the collection 37 | app.page('a.hbs', {content: 'this is {{name}}', data: {name: 'Foo'}}); 38 | app.page('b.hbs', {content: 'this is {{name}}', data: {name: 'Bar'}}); 39 | app.page('c.hbs', {content: 'this is {{name}}', data: {name: 'Baz'}}); 40 | 41 | // register an engine for rendering ".hbs" files 42 | app.engine('hbs', require('engine-handlebars')); 43 | 44 | // ask the user which "pages" they want to render 45 | // and write to the file system 46 | app.selectViews('pages', function(err, views) { 47 | if (err) { 48 | console.log(err); 49 | return; 50 | } 51 | console.log('done!'); 52 | }); 53 | ``` 54 | 55 | ## Related projects 56 | 57 | You might also be interested in these projects: 58 | 59 | * [assemble-fs](https://www.npmjs.com/package/assemble-fs): Assemble plugin to add methods to assemble for working with the file system, like src,… [more](https://www.npmjs.com/package/assemble-fs) | [homepage](https://github.com/assemble/assemble-fs) 60 | * [assemble](https://www.npmjs.com/package/assemble): Assemble is a powerful, extendable and easy to use static site generator for node.js. Used… [more](https://www.npmjs.com/package/assemble) | [homepage](https://github.com/assemble/assemble) 61 | * [base-questions](https://www.npmjs.com/package/base-questions): Plugin for base-methods that adds methods for prompting the user and storing the answers on… [more](https://www.npmjs.com/package/base-questions) | [homepage](https://github.com/node-base/base-questions) 62 | * [base](https://www.npmjs.com/package/base): base is the foundation for creating modular, unit testable and highly pluggable node.js applications, starting… [more](https://www.npmjs.com/package/base) | [homepage](https://github.com/node-base/base) 63 | 64 | ## Contributing 65 | 66 | Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/assemble/assemble-select-views/issues/new). 67 | 68 | ## Building docs 69 | 70 | Generate readme and API documentation with [verb](https://github.com/verbose/verb): 71 | 72 | ```sh 73 | $ npm install verb && npm run docs 74 | ``` 75 | 76 | Or, if [verb](https://github.com/verbose/verb) is installed globally: 77 | 78 | ```sh 79 | $ verb 80 | ``` 81 | 82 | ## Running tests 83 | 84 | Install dev dependencies: 85 | 86 | ```sh 87 | $ npm install -d && npm test 88 | ``` 89 | 90 | ## Author 91 | 92 | **Jon Schlinkert** 93 | 94 | * [github/jonschlinkert](https://github.com/jonschlinkert) 95 | * [twitter/jonschlinkert](http://twitter.com/jonschlinkert) 96 | 97 | ## License 98 | 99 | Copyright © 2016, [Jon Schlinkert](https://github.com/jonschlinkert). 100 | Released under the [MIT license](https://github.com/assemble/assemble-select-views/blob/master/LICENSE). 101 | 102 | *** 103 | 104 | _This file was generated by [verb](https://github.com/verbose/verb), v0.9.0, on May 09, 2016._ -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "ecmaFeatures": { 3 | "modules": true, 4 | "experimentalObjectRestSpread": true 5 | }, 6 | 7 | "env": { 8 | "browser": false, 9 | "es6": true, 10 | "node": true, 11 | "mocha": true 12 | }, 13 | 14 | "globals": { 15 | "document": false, 16 | "navigator": false, 17 | "window": false 18 | }, 19 | 20 | "rules": { 21 | "accessor-pairs": 2, 22 | "arrow-spacing": [2, { "before": true, "after": true }], 23 | "block-spacing": [2, "always"], 24 | "brace-style": [2, "1tbs", { "allowSingleLine": true }], 25 | "comma-dangle": [2, "never"], 26 | "comma-spacing": [2, { "before": false, "after": true }], 27 | "comma-style": [2, "last"], 28 | "constructor-super": 2, 29 | "curly": [2, "multi-line"], 30 | "dot-location": [2, "property"], 31 | "eol-last": 2, 32 | "eqeqeq": [2, "allow-null"], 33 | "generator-star-spacing": [2, { "before": true, "after": true }], 34 | "handle-callback-err": [2, "^(err|error)$" ], 35 | "indent": [2, 2, { "SwitchCase": 1 }], 36 | "key-spacing": [2, { "beforeColon": false, "afterColon": true }], 37 | "keyword-spacing": [2, { "before": true, "after": true }], 38 | "new-cap": [2, { "newIsCap": true, "capIsNew": false }], 39 | "new-parens": 2, 40 | "no-array-constructor": 2, 41 | "no-caller": 2, 42 | "no-class-assign": 2, 43 | "no-cond-assign": 2, 44 | "no-const-assign": 2, 45 | "no-control-regex": 2, 46 | "no-debugger": 2, 47 | "no-delete-var": 2, 48 | "no-dupe-args": 2, 49 | "no-dupe-class-members": 2, 50 | "no-dupe-keys": 2, 51 | "no-duplicate-case": 2, 52 | "no-empty-character-class": 2, 53 | "no-eval": 2, 54 | "no-ex-assign": 2, 55 | "no-extend-native": 2, 56 | "no-extra-bind": 2, 57 | "no-extra-boolean-cast": 2, 58 | "no-extra-parens": [2, "functions"], 59 | "no-fallthrough": 2, 60 | "no-floating-decimal": 2, 61 | "no-func-assign": 2, 62 | "no-implied-eval": 2, 63 | "no-inner-declarations": [2, "functions"], 64 | "no-invalid-regexp": 2, 65 | "no-irregular-whitespace": 2, 66 | "no-iterator": 2, 67 | "no-label-var": 2, 68 | "no-labels": 2, 69 | "no-lone-blocks": 2, 70 | "no-mixed-spaces-and-tabs": 2, 71 | "no-multi-spaces": 2, 72 | "no-multi-str": 2, 73 | "no-multiple-empty-lines": [2, { "max": 1 }], 74 | "no-native-reassign": 0, 75 | "no-negated-in-lhs": 2, 76 | "no-new": 2, 77 | "no-new-func": 2, 78 | "no-new-object": 2, 79 | "no-new-require": 2, 80 | "no-new-wrappers": 2, 81 | "no-obj-calls": 2, 82 | "no-octal": 2, 83 | "no-octal-escape": 2, 84 | "no-proto": 0, 85 | "no-redeclare": 2, 86 | "no-regex-spaces": 2, 87 | "no-return-assign": 2, 88 | "no-self-compare": 2, 89 | "no-sequences": 2, 90 | "no-shadow-restricted-names": 2, 91 | "no-spaced-func": 2, 92 | "no-sparse-arrays": 2, 93 | "no-this-before-super": 2, 94 | "no-throw-literal": 2, 95 | "no-trailing-spaces": 0, 96 | "no-undef": 2, 97 | "no-undef-init": 2, 98 | "no-unexpected-multiline": 2, 99 | "no-unneeded-ternary": [2, { "defaultAssignment": false }], 100 | "no-unreachable": 2, 101 | "no-unused-vars": [2, { "vars": "all", "args": "none" }], 102 | "no-useless-call": 0, 103 | "no-with": 2, 104 | "one-var": [0, { "initialized": "never" }], 105 | "operator-linebreak": [0, "after", { "overrides": { "?": "before", ":": "before" } }], 106 | "padded-blocks": [0, "never"], 107 | "quotes": [2, "single", "avoid-escape"], 108 | "radix": 2, 109 | "semi": [2, "always"], 110 | "semi-spacing": [2, { "before": false, "after": true }], 111 | "space-before-blocks": [2, "always"], 112 | "space-before-function-paren": [2, "never"], 113 | "space-in-parens": [2, "never"], 114 | "space-infix-ops": 2, 115 | "space-unary-ops": [2, { "words": true, "nonwords": false }], 116 | "spaced-comment": [0, "always", { "markers": ["global", "globals", "eslint", "eslint-disable", "*package", "!", ","] }], 117 | "use-isnan": 2, 118 | "valid-typeof": 2, 119 | "wrap-iife": [2, "any"], 120 | "yoda": [2, "never"] 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | require('mocha'); 4 | var assert = require('assert'); 5 | var assemble = require('assemble-core'); 6 | var questions = require('base-questions'); 7 | var conflicts = require('base-fs-conflicts'); 8 | var rename = require('base-fs-rename'); 9 | var exists = require('fs-exists-sync'); 10 | var selectViews = require('./'); 11 | var del = require('delete'); 12 | var app; 13 | 14 | describe('assemble-select-views', function() { 15 | describe('module', function() { 16 | it('should export a function', function() { 17 | assert.equal(typeof selectViews, 'function'); 18 | }); 19 | }); 20 | 21 | describe('plugin', function() { 22 | it('should only register the plugin once', function(cb) { 23 | var count = 0; 24 | app = assemble(); 25 | app.on('plugin', function(name) { 26 | if (name === 'assemble-select-views') { 27 | count++; 28 | } 29 | }); 30 | app.use(selectViews()); 31 | app.use(selectViews()); 32 | app.use(selectViews()); 33 | assert.equal(count, 1); 34 | cb(); 35 | }); 36 | }); 37 | 38 | describe('errors', function() { 39 | beforeEach(function() { 40 | app = assemble(); 41 | app.use(selectViews()); 42 | app.create('pages'); 43 | }); 44 | 45 | it('should throw an error when base-questions is not registered', function(cb) { 46 | app.use(conflicts()); 47 | app.use(rename()); 48 | 49 | app.selectViews('pages', function(err, views) { 50 | assert(err); 51 | assert.equal(err.message, 'expected the base-questions plugin to be registered'); 52 | cb(); 53 | }); 54 | }); 55 | 56 | it('should throw an error when base-fs-conflicts is not registered', function(cb) { 57 | app.use(questions()); 58 | app.use(rename()); 59 | 60 | app.selectViews('pages', function(err, views) { 61 | assert(err); 62 | assert.equal(err.message, 'expected the base-fs-conflicts plugin to be registered'); 63 | cb(); 64 | }); 65 | }); 66 | 67 | it('should throw an error when base-fs-rename is not registered', function(cb) { 68 | app.use(questions()); 69 | app.use(conflicts()); 70 | 71 | app.selectViews('pages', function(err, views) { 72 | assert(err); 73 | assert.equal(err.message, 'expected the base-fs-rename plugin to be registered'); 74 | cb(); 75 | }); 76 | }); 77 | 78 | it('should throw an error when base-fs-rename is not registered', function(cb) { 79 | app.use(questions()); 80 | app.use(conflicts()); 81 | 82 | app.selectViews('pages', function(err, views) { 83 | assert(err); 84 | assert.equal(err.message, 'expected the base-fs-rename plugin to be registered'); 85 | cb(); 86 | }); 87 | }); 88 | 89 | it('should throw an error when the options.collection is not defined', function(cb) { 90 | app.create('posts'); 91 | app.use(questions()); 92 | app.use(conflicts()); 93 | app.use(rename()); 94 | 95 | app.selectViews(function(err, views) { 96 | assert(err); 97 | assert.equal(err.message, 'expected options.collection to be a string'); 98 | cb(); 99 | }); 100 | }); 101 | }); 102 | 103 | describe('plugin', function() { 104 | this.timeout(10000); 105 | 106 | beforeEach(function() { 107 | app = assemble(); 108 | app.use(questions()); 109 | app.use(conflicts()); 110 | app.use(rename()); 111 | app.use(selectViews()); 112 | app.create('pages'); 113 | }); 114 | 115 | afterEach(function(cb) { 116 | del('actual', cb); 117 | }); 118 | 119 | it('should render views specified on the `selectViews` option', function(cb) { 120 | app.page('foo.hbs', {content: 'this is {{name}}', data: {name: 'Foo'}}); 121 | app.page('bar.hbs', {content: 'this is {{name}}'}); 122 | app.page('baz.hbs', {content: 'this is {{name}}'}); 123 | app.data({name: 'blah'}); 124 | 125 | app.engine('hbs', require('engine-handlebars')); 126 | app.option('selectViews', ['baz', 'foo']); 127 | app.option('dest', 'actual'); 128 | 129 | app.selectViews('pages', function(err, views) { 130 | if (err) return cb(err); 131 | assert(exists('actual/foo.hbs')); 132 | assert(exists('actual/baz.hbs')); 133 | cb(); 134 | }); 135 | }); 136 | }); 137 | }); 138 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var path = require('path'); 4 | var extend = require('extend-shallow'); 5 | var cwd = require('base-cwd'); 6 | 7 | module.exports = function(config) { 8 | config = config || {}; 9 | 10 | return function plugin(app) { 11 | if (!isValidInstance(app)) { 12 | return; 13 | } 14 | 15 | app.use(cwd()); 16 | 17 | this.define('selectViews', function(name, options, cb) { 18 | if (typeof name === 'function') { 19 | cb = name; 20 | name = null; 21 | options = {}; 22 | } 23 | 24 | if (typeof options === 'function') { 25 | cb = options; 26 | options = {}; 27 | } 28 | 29 | if (typeof options === 'string') { 30 | var dest = options; 31 | options = {}; 32 | options.dest = dest; 33 | } 34 | 35 | // lazily ensure the correct plugins are loaded 36 | var err = verifyPlugins(this); 37 | if (err instanceof Error) { 38 | cb(err); 39 | return; 40 | } 41 | 42 | // merge options 43 | var opts = extend({}, config, this.options, options); 44 | if (typeof name === 'undefined' || name == null) { 45 | name = getCollectionName(app, opts); 46 | if (name instanceof Error) { 47 | cb(name); 48 | return; 49 | } 50 | } 51 | 52 | var renderFn = renderChoices(app, name); 53 | 54 | // get the specified view collection 55 | var views = this.getViews(name); 56 | if (typeof views === 'undefined') { 57 | cb(new Error('cannot find collection ' + name)); 58 | return; 59 | } 60 | 61 | var keys = Object.keys(views); 62 | if (!keys.length) { 63 | cb(new Error('no views found in collection: ' + name)); 64 | return; 65 | } 66 | 67 | if (keys.length === 1) { 68 | renderFn(keys, opts, cb); 69 | return; 70 | } 71 | 72 | if (opts.selectViews) { 73 | renderFn(opts.selectViews, opts, cb); 74 | return; 75 | } 76 | 77 | var msg = opts.message || 'Which views do you want to render?'; 78 | 79 | // setup a `choices` questions 80 | this.question('selectViewsDest', 'Destination directory?'); 81 | this.choices('selectViews', msg, keys); 82 | 83 | // prompt the user 84 | this.ask('selectViews', function(err, answers) { 85 | if (err) { 86 | cb(err); 87 | return; 88 | } 89 | 90 | if (answers.selectViews && answers.selectViews.length) { 91 | if (!opts.dest) { 92 | app.ask('selectViewsDest', {save: false}, function(err, answers) { 93 | if (err) { 94 | cb(err); 95 | return; 96 | } 97 | opts.dest = path.resolve(app.cwd, answers.dest); 98 | renderFn(answers.selectViews, opts, cb); 99 | }); 100 | return; 101 | } 102 | 103 | renderFn(answers.selectViews, opts, cb); 104 | } else { 105 | console.log('no views chosen'); 106 | cb(); 107 | } 108 | }); 109 | }); 110 | 111 | return plugin; 112 | }; 113 | }; 114 | 115 | function renderChoices(app, name) { 116 | var rendered = []; 117 | return function(files, options, cb) { 118 | app.data({options: options}); 119 | 120 | app.toStream(name, filter(options, files)).on('error', cb) 121 | .pipe(app.renderFile(options)).on('error', cb) 122 | .pipe(app.conflicts(options.dest)).on('error', cb) 123 | .pipe(app.dest(function(file) { 124 | if (options.flatten) { 125 | file.base = path.dirname(file.path); 126 | } 127 | rendered.push(file); 128 | return options.dest; 129 | })) 130 | .on('error', cb) 131 | .on('end', function() { 132 | cb(null, rendered); 133 | }); 134 | }; 135 | } 136 | 137 | function getCollectionName(app, options) { 138 | var name = options.collection; 139 | if (typeof name === 'undefined') { 140 | var names = Object.keys(app.views); 141 | if (names.length > 1) { 142 | return new Error('expected options.collection to be a string'); 143 | } 144 | name = names[0]; 145 | } 146 | return name; 147 | } 148 | 149 | function filter(options, arr) { 150 | if (typeof options.filter === 'function') { 151 | return options.filter(arr); 152 | } 153 | return arr; 154 | } 155 | 156 | function verifyPlugins(app) { 157 | // these plugins are not included in assemble by default 158 | if (typeof app.ask !== 'function') { 159 | return new Error('expected the base-questions plugin to be registered'); 160 | } 161 | if (typeof app.conflicts !== 'function') { 162 | return new Error('expected the base-fs-conflicts plugin to be registered'); 163 | } 164 | if (typeof app.rename !== 'function') { 165 | return new Error('expected the base-fs-rename plugin to be registered'); 166 | } 167 | 168 | // these plugins are included in assemble, but will need to 169 | // be registered if using `base` directly 170 | if (typeof app.src !== 'function') { 171 | return new Error('expected the base-fs plugin to be registered'); 172 | } 173 | if (typeof app.renderFile !== 'function') { 174 | return new Error('expected the assemble-render-file plugin to be registered'); 175 | } 176 | } 177 | 178 | function isValidInstance(app) { 179 | if (!app.isApp && !app.isGenerator && !app.isViews) { 180 | return false; 181 | } 182 | if (app.isRegistered('assemble-select-views')) { 183 | return false; 184 | } 185 | return true; 186 | } 187 | --------------------------------------------------------------------------------