├── fixtures ├── a.hbs ├── b.hbs ├── c.hbs ├── multiple │ ├── button.hbs │ └── page.hbs └── engines │ ├── a.hbs │ ├── b.hbs │ └── c.hbs ├── .gitattributes ├── .gitignore ├── .travis.yml ├── utils.js ├── .editorconfig ├── gulpfile.js ├── LICENSE ├── .verb.md ├── package.json ├── backup.js ├── index.js ├── README.md ├── .eslintrc.json └── test.js /fixtures/a.hbs: -------------------------------------------------------------------------------- 1 |

{{title}}

2 |

<%= title() %>

-------------------------------------------------------------------------------- /fixtures/b.hbs: -------------------------------------------------------------------------------- 1 |

{{title}}

2 |

<%= title() %>

-------------------------------------------------------------------------------- /fixtures/c.hbs: -------------------------------------------------------------------------------- 1 |

{{title}}

2 |

<%= title() %>

-------------------------------------------------------------------------------- /fixtures/multiple/button.hbs: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /fixtures/engines/a.hbs: -------------------------------------------------------------------------------- 1 |

{{title}}

2 |

<%= title %>

-------------------------------------------------------------------------------- /fixtures/engines/b.hbs: -------------------------------------------------------------------------------- 1 |

{{title}}

2 |

<%= title %>

-------------------------------------------------------------------------------- /fixtures/engines/c.hbs: -------------------------------------------------------------------------------- 1 |

{{title}}

2 |

<%= title %>

-------------------------------------------------------------------------------- /fixtures/multiple/page.hbs: -------------------------------------------------------------------------------- 1 | {{> button }} 2 | {{> button }} 3 | {{> button }} 4 | {{> button }} 5 | {{> button }} 6 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | *.sublime-* 3 | _gh_pages 4 | bower_components 5 | node_modules 6 | npm-debug.log 7 | actual 8 | test/actual 9 | temp 10 | tmp 11 | TODO.md 12 | vendor 13 | .idea 14 | benchmark 15 | coverage 16 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /utils.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Module dependencies 5 | */ 6 | 7 | var utils = require('lazy-cache')(require); 8 | var fn = require; 9 | 10 | require = utils; 11 | require('mixin-deep', 'merge'); 12 | require('through2', 'through'); 13 | require = fn; 14 | 15 | utils.debug = require('debug')('base:assemble:assemble-compile-file'); 16 | 17 | /** 18 | * Expose `utils` 19 | */ 20 | 21 | module.exports = utils; 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 | [test/**] 17 | trim_trailing_whitespace = false 18 | insert_final_newline = false 19 | 20 | [templates/**] 21 | trim_trailing_whitespace = false 22 | insert_final_newline = false 23 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var gulp = require('gulp'); 4 | var mocha = require('gulp-mocha'); 5 | var istanbul = require('gulp-istanbul'); 6 | var eslint = require('gulp-eslint'); 7 | 8 | var lint = ['index.js', 'utils.js', 'test.js']; 9 | 10 | gulp.task('coverage', function() { 11 | return gulp.src('index.js') 12 | .pipe(istanbul()) 13 | .pipe(istanbul.hookRequire()); 14 | }); 15 | 16 | gulp.task('mocha', ['coverage'], function() { 17 | return gulp.src('test.js') 18 | .pipe(mocha({reporter: 'spec'})) 19 | .pipe(istanbul.writeReports()) 20 | }); 21 | 22 | gulp.task('eslint', function() { 23 | return gulp.src(lint) 24 | .pipe(eslint()) 25 | }); 26 | 27 | gulp.task('default', ['mocha', 'eslint']); 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015-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 | ## Usage 2 | 3 | **WIP! This is not 100% ready for production use!** Please feel free to play around with it if you want. Feedback or bug reports welcome. 4 | 5 | ```js 6 | var compileFile = require('{%= name %}'); 7 | var assemble = require('assemble'); 8 | 9 | // register as an instance plugin with assemble 10 | var app = assemble() 11 | .use(compileFile()); 12 | 13 | // then use in a vinyl pipeline 14 | app.src('*.hbs') 15 | .pipe(app.compilefile()) 16 | .pipe(app.dest('foo')); 17 | ``` 18 | 19 | ### noop engine 20 | 21 | By default, when no engine is found for a file an error is thrown. To get around this you can either define a `noop` engine, or use disable the [engineStrict option](#optionsengineStrict). 22 | 23 | A noop engine follows the same signature as any engine, but must be registered using the key: `noop`. 24 | 25 | **Example** 26 | 27 | ```js 28 | app.engine('noop', function(view, opts, next) { 29 | // do whatever you want to `view`, or nothing 30 | next(null, view); 31 | }); 32 | ``` 33 | 34 | ## Options 35 | 36 | ### options.engineStrict 37 | 38 | By default, when no engine is found for a file an error is thrown. This can be disabled with the following: 39 | 40 | ```js 41 | app.option('engineStrict', false); 42 | ``` 43 | 44 | When disabled and an engine is not found, files are just passed through. 45 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "assemble-compile-file", 3 | "description": "Assemble plugin for compiling views (in a vinyl pipeline) that might need to be rendered more than once.", 4 | "version": "0.1.0", 5 | "homepage": "https://github.com/jonschlinkert/assemble-compile-file", 6 | "author": "Jon Schlinkert (https://github.com/jonschlinkert)", 7 | "repository": "jonschlinkert/assemble-compile-file", 8 | "bugs": { 9 | "url": "https://github.com/jonschlinkert/assemble-compile-file/issues" 10 | }, 11 | "license": "MIT", 12 | "files": [ 13 | "index.js", 14 | "utils.js" 15 | ], 16 | "main": "index.js", 17 | "engines": { 18 | "node": ">=0.10.0" 19 | }, 20 | "scripts": { 21 | "test": "mocha" 22 | }, 23 | "dependencies": { 24 | "debug": "^2.2.0", 25 | "lazy-cache": "^1.0.3", 26 | "mixin-deep": "^1.1.3", 27 | "through2": "^2.0.1" 28 | }, 29 | "devDependencies": { 30 | "assemble-core": "^0.13.2", 31 | "async": "^1.5.2", 32 | "engine-base": "^0.1.2", 33 | "engine-handlebars": "^0.8.0", 34 | "gulp": "^3.9.1", 35 | "gulp-eslint": "^2.0.0", 36 | "gulp-format-md": "^0.1.7", 37 | "gulp-istanbul": "^0.10.3", 38 | "gulp-mocha": "^2.2.0", 39 | "mocha": "^2.4.5", 40 | "should": "^8.2.2" 41 | }, 42 | "keywords": [ 43 | "assemble", 44 | "assembleplugin", 45 | "engine", 46 | "file", 47 | "plugin", 48 | "compile", 49 | "stream", 50 | "template", 51 | "view", 52 | "views", 53 | "vinyl" 54 | ], 55 | "verb": { 56 | "run": true, 57 | "toc": false, 58 | "layout": "default", 59 | "tasks": [ 60 | "readme" 61 | ], 62 | "plugins": [ 63 | "gulp-format-md" 64 | ], 65 | "related": { 66 | "list": [ 67 | "assemble", 68 | "assemble-loader", 69 | "assemble-streams", 70 | "verb", 71 | "base" 72 | ] 73 | }, 74 | "reflinks": [ 75 | "verb" 76 | ], 77 | "lint": { 78 | "reflinks": true 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /backup.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * assemble-compile-file 3 | * 4 | * Copyright (c) 2015, Jon Schlinkert. 5 | * Licensed under the MIT License. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | var utils = require('./utils'); 11 | 12 | /** 13 | * Compile a vinyl file. 14 | * 15 | * ```js 16 | * app.src('*.hbs') 17 | * .pipe(app.compileFile()); 18 | * ``` 19 | * 20 | * @name .compileFile 21 | * @param {Object} `locals` Optionally locals to pass to the template engine for compileing. 22 | * @return {Object} 23 | * @api public 24 | */ 25 | 26 | module.exports = function(config) { 27 | return function(app) { 28 | config = utils.merge({}, app.options, config); 29 | 30 | // create a placeholder collection that can be accessed if needed, 31 | // with a name that is unlikely to cause collissions 32 | if (!app.streamFiles) { 33 | app.create('streamFiles'); 34 | } 35 | 36 | app.define('compileFile', function(engine, locals) { 37 | if (typeof engine !== 'string') { 38 | locals = engine; 39 | engine = null; 40 | } 41 | 42 | var opts = {}; 43 | if (locals && !locals.isCollection) { 44 | opts = utils.merge({}, config, locals); 45 | } 46 | 47 | var View = opts.View || opts.File || app.View; 48 | var collection = app.collection(); 49 | 50 | return utils.through.obj(function(file, enc, next) { 51 | if (file.isNull()) { 52 | return next(null, file); 53 | } 54 | 55 | if (!file.isView) { 56 | // file = app.streamFiles(file.path, file); 57 | file = collection.view(file.path, file); 58 | } 59 | 60 | // run `onLoad` middleware 61 | app.handleView('onLoad', file); 62 | 63 | // create the context to pass to templates 64 | var ctx = utils.merge({}, app.cache.data, locals, file.data); 65 | 66 | // resolve template engine 67 | ctx.engine = resolveEngine(app, ctx, engine); 68 | // if (!ctx.engine && app.option('engineStrict') !== true) { 69 | // console.log(file) 70 | // next(null, file); 71 | // return; 72 | // } 73 | 74 | // compile the file 75 | app.compile(file, ctx, function(err, res) { 76 | if (err) { 77 | err.file = file; 78 | next(err); 79 | return; 80 | } 81 | 82 | var view = new View(res); 83 | if (engine) delete view.fn; 84 | 85 | next(null, res); 86 | }); 87 | }); 88 | }); 89 | }; 90 | }; 91 | 92 | function resolveEngine(app, ctx, engine) { 93 | ctx.engine = engine || ctx.engine; 94 | 95 | // allow a `noop` engine to be defined 96 | if (!ctx.engine && app.engines['.noop']) { 97 | ctx.engine = '.noop'; 98 | } 99 | 100 | return ctx.engine; 101 | } 102 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * assemble-compile-file 3 | * 4 | * Copyright (c) 2015, Jon Schlinkert. 5 | * Licensed under the MIT License. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | var utils = require('./utils'); 11 | var debug = utils.debug; 12 | 13 | /** 14 | * Compile a vinyl file. 15 | * 16 | * ```js 17 | * app.src('*.hbs') 18 | * .pipe(app.compileFile()); 19 | * ``` 20 | * 21 | * @name .compileFile 22 | * @param {Object} `locals` Optionally locals to pass to the template engine for compileing. 23 | * @return {Object} 24 | * @api public 25 | */ 26 | 27 | module.exports = function(config) { 28 | return function plugin(app) { 29 | if (!isValidInstance(this)) return; 30 | config = utils.merge({}, app.options, config); 31 | 32 | app.define('compileFile', function(engine, locals) { 33 | if (typeof engine !== 'string') { 34 | locals = engine; 35 | engine = null; 36 | } 37 | 38 | debug('compileFile: engine "%s"', engine); 39 | var opts = {}; 40 | 41 | if (locals && !locals.isCollection) { 42 | opts = utils.merge({}, config, locals); 43 | } 44 | 45 | var View = opts.View || opts.File || app.View; 46 | 47 | return utils.through.obj(function(file, enc, next) { 48 | if (file.isNull()) { 49 | return next(null, file); 50 | } 51 | 52 | if (!file.isView) file = new View(file); 53 | 54 | // run `onLoad` middleware 55 | app.handle('onLoad', file, function(err, view) { 56 | if (err) return next(err); 57 | 58 | debug('compileFile, preCompile: %s', view.relative); 59 | 60 | // create the context to pass to templates 61 | var ctx = utils.merge({}, app.cache.data, locals, view.data); 62 | ctx.engine = resolveEngine(app, ctx, engine); 63 | 64 | if (!ctx.engine && app.option('engineStrict') === false) { 65 | next(null, view); 66 | return; 67 | } 68 | 69 | // compile the view 70 | app.compileAsync(view, ctx, function(err, res) { 71 | if (err) { 72 | err.view = view; 73 | next(err); 74 | return; 75 | } 76 | 77 | debug('compileFile, postCompile: %s', view.relative); 78 | next(null, res); 79 | }); 80 | }); 81 | }); 82 | }); 83 | 84 | return plugin; 85 | }; 86 | }; 87 | 88 | function resolveEngine(app, ctx, engine) { 89 | ctx.engine = engine || ctx.engine; 90 | 91 | // allow a `noop` engine to be defined 92 | if (!ctx.engine && app.engines['.noop']) { 93 | ctx.engine = '.noop'; 94 | } 95 | 96 | return ctx.engine; 97 | } 98 | 99 | function isValidInstance(app) { 100 | if (app.isView || app.isItem) { 101 | return false; 102 | } 103 | if (app.isRegistered('assemble-render-file')) { 104 | return false; 105 | } 106 | return true; 107 | } 108 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # assemble-compile-file [![NPM version](https://img.shields.io/npm/v/assemble-compile-file.svg?style=flat)](https://www.npmjs.com/package/assemble-compile-file) [![NPM downloads](https://img.shields.io/npm/dm/assemble-compile-file.svg?style=flat)](https://npmjs.org/package/assemble-compile-file) [![Build Status](https://img.shields.io/travis/jonschlinkert/assemble-compile-file.svg?style=flat)](https://travis-ci.org/jonschlinkert/assemble-compile-file) 2 | 3 | > Assemble plugin for compiling views (in a vinyl pipeline) that might need to be rendered more than once. 4 | 5 | ## Install 6 | 7 | Install with [npm](https://www.npmjs.com/): 8 | 9 | ```sh 10 | $ npm install assemble-compile-file --save 11 | ``` 12 | 13 | ## Usage 14 | 15 | **WIP! This is not 100% ready for production use!** 16 | 17 | Please feel free to play around with it if you want. Feedback or bug reports welcome. 18 | 19 | ```js 20 | var compileFile = require('assemble-compile-file'); 21 | var assemble = require('assemble'); 22 | 23 | // register as an instance plugin with assemble 24 | var app = assemble() 25 | .use(compileFile()); 26 | 27 | // then use in a vinyl pipeline 28 | app.src('*.hbs') 29 | .pipe(app.compilefile()) 30 | .pipe(app.dest('foo')); 31 | ``` 32 | 33 | ### noop engine 34 | 35 | By default, when no engine is found for a file an error is thrown. To get around this you can either define a `noop` engine, or use disable the [engineStrict option](#optionsengineStrict). 36 | 37 | A noop engine follows the same signature as any engine, but must be registered using the key: `noop`. 38 | 39 | **Example** 40 | 41 | ```js 42 | app.engine('noop', function(view, opts, next) { 43 | // do whatever you want to `view`, or nothing 44 | next(null, view); 45 | }); 46 | ``` 47 | 48 | ## Options 49 | 50 | ### options.engineStrict 51 | 52 | By default, when no engine is found for a file an error is thrown. This can be disabled with the following: 53 | 54 | ```js 55 | app.option('engineStrict', false); 56 | ``` 57 | 58 | When disabled and an engine is not found, files are just passed through. 59 | 60 | ## Related projects 61 | 62 | You might also be interested in these projects: 63 | 64 | * [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) 65 | * [assemble-loader](https://www.npmjs.com/package/assemble-loader): Assemble plugin (^0.6.0) for loading globs of views onto custom view collections. Also works with… [more](https://www.npmjs.com/package/assemble-loader) | [homepage](https://github.com/jonschlinkert/assemble-loader) 66 | * [assemble-streams](https://www.npmjs.com/package/assemble-streams): Assemble pipeline plugin for pushing a view collection into a vinyl stream. | [homepage](https://github.com/assemble/assemble-streams) 67 | * [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) 68 | * [verb](https://www.npmjs.com/package/verb): Documentation generator for GitHub projects. Verb is extremely powerful, easy to use, and is used… [more](https://www.npmjs.com/package/verb) | [homepage](https://github.com/verbose/verb) 69 | 70 | ## Contributing 71 | 72 | Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/assemble-compile-file/issues/new). 73 | 74 | ## Building docs 75 | 76 | Generate readme and API documentation with [verb](https://github.com/verbose/verb): 77 | 78 | ```sh 79 | $ npm install verb && npm run docs 80 | ``` 81 | 82 | Or, if [verb](https://github.com/verbose/verb) is installed globally: 83 | 84 | ```sh 85 | $ verb 86 | ``` 87 | 88 | ## Running tests 89 | 90 | Install dev dependencies: 91 | 92 | ```sh 93 | $ npm install -d && npm test 94 | ``` 95 | 96 | ## Author 97 | 98 | **Jon Schlinkert** 99 | 100 | * [github/jonschlinkert](https://github.com/jonschlinkert) 101 | * [twitter/jonschlinkert](http://twitter.com/jonschlinkert) 102 | 103 | ## License 104 | 105 | Copyright © 2016, [Jon Schlinkert](https://github.com/jonschlinkert). 106 | Released under the [MIT license](https://github.com/jonschlinkert/assemble-compile-file/blob/master/LICENSE). 107 | 108 | *** 109 | 110 | _This file was generated by [verb](https://github.com/verbose/verb), v, on April 05, 2016._ -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "ecmaFeatures": { 3 | "modules": true, 4 | "experimentalObjectRestSpread": true 5 | }, 6 | "env": { 7 | "browser": false, 8 | "es6": true, 9 | "node": true, 10 | "mocha": true 11 | }, 12 | "globals": { 13 | "document": false, 14 | "navigator": false, 15 | "window": false 16 | }, 17 | "rules": { 18 | "accessor-pairs": 2, 19 | "arrow-spacing": [ 20 | 2, 21 | { 22 | "before": true, 23 | "after": true 24 | } 25 | ], 26 | "block-spacing": [ 27 | 2, 28 | "always" 29 | ], 30 | "brace-style": [ 31 | 2, 32 | "1tbs", 33 | { 34 | "allowSingleLine": true 35 | } 36 | ], 37 | "comma-dangle": [ 38 | 2, 39 | "never" 40 | ], 41 | "comma-spacing": [ 42 | 2, 43 | { 44 | "before": false, 45 | "after": true 46 | } 47 | ], 48 | "comma-style": [ 49 | 2, 50 | "last" 51 | ], 52 | "constructor-super": 2, 53 | "curly": [ 54 | 2, 55 | "multi-line" 56 | ], 57 | "dot-location": [ 58 | 2, 59 | "property" 60 | ], 61 | "eol-last": 2, 62 | "eqeqeq": [ 63 | 2, 64 | "allow-null" 65 | ], 66 | "generator-star-spacing": [ 67 | 2, 68 | { 69 | "before": true, 70 | "after": true 71 | } 72 | ], 73 | "handle-callback-err": [ 74 | 2, 75 | "^(err|error)$" 76 | ], 77 | "indent": [ 78 | 2, 79 | 2, 80 | { 81 | "SwitchCase": 1 82 | } 83 | ], 84 | "key-spacing": [ 85 | 2, 86 | { 87 | "beforeColon": false, 88 | "afterColon": true 89 | } 90 | ], 91 | "new-cap": [ 92 | 2, 93 | { 94 | "newIsCap": true, 95 | "capIsNew": false 96 | } 97 | ], 98 | "new-parens": 2, 99 | "no-array-constructor": 2, 100 | "no-caller": 2, 101 | "no-class-assign": 2, 102 | "no-cond-assign": 2, 103 | "no-const-assign": 2, 104 | "no-control-regex": 2, 105 | "no-debugger": 2, 106 | "no-delete-var": 2, 107 | "no-dupe-args": 2, 108 | "no-dupe-class-members": 2, 109 | "no-dupe-keys": 2, 110 | "no-duplicate-case": 2, 111 | "no-empty-character-class": 2, 112 | "no-empty-label": 2, 113 | "no-eval": 2, 114 | "no-ex-assign": 2, 115 | "no-extend-native": 2, 116 | "no-extra-bind": 2, 117 | "no-extra-boolean-cast": 2, 118 | "no-extra-parens": [ 119 | 2, 120 | "functions" 121 | ], 122 | "no-fallthrough": 2, 123 | "no-floating-decimal": 2, 124 | "no-func-assign": 2, 125 | "no-implied-eval": 2, 126 | "no-inner-declarations": [ 127 | 2, 128 | "functions" 129 | ], 130 | "no-invalid-regexp": 2, 131 | "no-irregular-whitespace": 2, 132 | "no-iterator": 2, 133 | "no-label-var": 2, 134 | "no-labels": 2, 135 | "no-lone-blocks": 2, 136 | "no-mixed-spaces-and-tabs": 2, 137 | "no-multi-spaces": 2, 138 | "no-multi-str": 2, 139 | "no-multiple-empty-lines": [ 140 | 2, 141 | { 142 | "max": 1 143 | } 144 | ], 145 | "no-native-reassign": 2, 146 | "no-negated-in-lhs": 2, 147 | "no-new": 2, 148 | "no-new-func": 2, 149 | "no-new-object": 2, 150 | "no-new-require": 2, 151 | "no-new-wrappers": 2, 152 | "no-obj-calls": 2, 153 | "no-octal": 2, 154 | "no-octal-escape": 2, 155 | "no-proto": 0, 156 | "no-redeclare": 2, 157 | "no-regex-spaces": 2, 158 | "no-return-assign": 2, 159 | "no-self-compare": 2, 160 | "no-sequences": 2, 161 | "no-shadow-restricted-names": 2, 162 | "no-spaced-func": 2, 163 | "no-sparse-arrays": 2, 164 | "no-this-before-super": 2, 165 | "no-throw-literal": 2, 166 | "no-trailing-spaces": 0, 167 | "no-undef": 2, 168 | "no-undef-init": 2, 169 | "no-unexpected-multiline": 2, 170 | "no-unneeded-ternary": [ 171 | 2, 172 | { 173 | "defaultAssignment": false 174 | } 175 | ], 176 | "no-unreachable": 2, 177 | "no-unused-vars": [ 178 | 2, 179 | { 180 | "vars": "all", 181 | "args": "none" 182 | } 183 | ], 184 | "no-useless-call": 0, 185 | "no-with": 2, 186 | "one-var": [ 187 | 0, 188 | { 189 | "initialized": "never" 190 | } 191 | ], 192 | "operator-linebreak": [ 193 | 0, 194 | "after", 195 | { 196 | "overrides": { 197 | "?": "before", 198 | ":": "before" 199 | } 200 | } 201 | ], 202 | "padded-blocks": [ 203 | 0, 204 | "never" 205 | ], 206 | "quotes": [ 207 | 2, 208 | "single", 209 | "avoid-escape" 210 | ], 211 | "radix": 2, 212 | "semi": [ 213 | 2, 214 | "always" 215 | ], 216 | "semi-spacing": [ 217 | 2, 218 | { 219 | "before": false, 220 | "after": true 221 | } 222 | ], 223 | "space-after-keywords": [ 224 | 2, 225 | "always" 226 | ], 227 | "space-before-blocks": [ 228 | 2, 229 | "always" 230 | ], 231 | "space-before-function-paren": [ 232 | 2, 233 | "never" 234 | ], 235 | "space-before-keywords": [ 236 | 2, 237 | "always" 238 | ], 239 | "space-in-parens": [ 240 | 2, 241 | "never" 242 | ], 243 | "space-infix-ops": 2, 244 | "space-return-throw-case": 2, 245 | "space-unary-ops": [ 246 | 2, 247 | { 248 | "words": true, 249 | "nonwords": false 250 | } 251 | ], 252 | "spaced-comment": [ 253 | 0, 254 | "always", 255 | { 256 | "markers": [ 257 | "global", 258 | "globals", 259 | "eslint", 260 | "eslint-disable", 261 | "*package", 262 | "!", 263 | "," 264 | ] 265 | } 266 | ], 267 | "use-isnan": 2, 268 | "valid-typeof": 2, 269 | "wrap-iife": [ 270 | 2, 271 | "any" 272 | ], 273 | "yoda": [ 274 | 2, 275 | "never" 276 | ] 277 | } 278 | } 279 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | require('mocha'); 4 | require('should'); 5 | var async = require('async'); 6 | var Assemble = require('assemble-core'); 7 | // var renderFile = require('assemble-render-file'); 8 | var through = require('through2'); 9 | var assert = require('assert'); 10 | var compileFile = require('./'); 11 | var path = require('path'); 12 | var app; 13 | 14 | var cwd = path.resolve.bind(path, __dirname, 'fixtures'); 15 | 16 | function renderFile(options) { 17 | return function(app) { 18 | app.define('renderFile', function(engine, locals) { 19 | if (typeof engine !== 'string') { 20 | locals = engine; 21 | engine = null; 22 | } 23 | 24 | locals = locals || {}; 25 | if (typeof engine === 'string' && engine.charAt(0) !== '.') { 26 | engine = '.' + engine; 27 | } 28 | 29 | return through.obj(function(file, enc, next) { 30 | var fn = engine ? file.engineStack[engine] : file.fn; 31 | 32 | app.handle('preRender', file, function(err, view) { 33 | if (err) return next(err); 34 | 35 | if (typeof fn === 'function') { 36 | var ctx = view.context(locals); 37 | view.contents = new Buffer(fn(ctx)); 38 | 39 | for (var key in file.engineStack) { 40 | var engine = app.engine(key); 41 | var newFn = engine.compile(view.content, ctx); 42 | app.constructor.utils.engineStack(view, key, newFn); 43 | } 44 | 45 | app.handle('postRender', view, next); 46 | } 47 | }); 48 | }); 49 | }); 50 | } 51 | }; 52 | 53 | describe('app.compileFile()', function() { 54 | beforeEach(function() { 55 | app = new Assemble() 56 | .use(compileFile()) 57 | .use(renderFile()) 58 | 59 | app.engine('hbs', require('engine-handlebars')); 60 | app.engine('tmpl', require('engine-base')); 61 | app.engine('*', require('engine-base')); 62 | 63 | app.create('files', {engine: '*'}); 64 | app.file('a', {content: 'this is <%= title() %>'}); 65 | app.file('b', {content: 'this is <%= title() %>'}); 66 | app.file('c', {content: 'this is <%= title() %>'}); 67 | 68 | app.option('renameKey', function(key) { 69 | return path.basename(key, path.extname(key)); 70 | }); 71 | 72 | app.helper('title', function() { 73 | if (this.context.title) { 74 | return this.context.title; 75 | } 76 | var view = this.context.view; 77 | var title = view.title || view.data.title; 78 | if (title) { 79 | return title; 80 | } 81 | var key = view.key; 82 | var ctx = this.context[key]; 83 | if (ctx && ctx.title) return ctx.title; 84 | return key; 85 | }); 86 | }); 87 | 88 | it('should compile views from src', function(cb) { 89 | var stream = app.src(cwd('*.hbs')); 90 | var files = []; 91 | 92 | stream.pipe(app.compileFile()) 93 | .on('error', cb) 94 | .on('data', function(file) { 95 | files.push(file); 96 | }) 97 | .on('end', function() { 98 | assert.equal(files[0].basename, 'a.hbs'); 99 | assert.equal(files[1].basename, 'b.hbs'); 100 | assert.equal(files[2].basename, 'c.hbs'); 101 | cb(); 102 | }); 103 | }); 104 | 105 | it('should compile views with the engine that matches the file extension', function(cb) { 106 | var stream = app.src(cwd('*.hbs')); 107 | var files = []; 108 | 109 | stream.pipe(app.compileFile()) 110 | .on('error', cb) 111 | .on('data', function(file) { 112 | files.push(file); 113 | }) 114 | .on('end', function() { 115 | assert(typeof files[0].fn, 'function'); 116 | assert.equal(typeof files[1].fn, 'function'); 117 | assert.equal(typeof files[2].fn, 'function'); 118 | cb(); 119 | }); 120 | }); 121 | 122 | it.only('should compile views with multiple engines', function(cb) { 123 | var stream = app.src(cwd('*.hbs')); 124 | var files = []; 125 | 126 | stream 127 | .pipe(app.compileFile('tmpl')) 128 | .pipe(app.compileFile('hbs')) 129 | .pipe(through.obj(function(file, enc, next) { 130 | console.log('compiled -------') 131 | console.log(file.content) 132 | next(null, file); 133 | })) 134 | .pipe(app.renderFile('hbs')) 135 | .pipe(through.obj(function(file, enc, next) { 136 | console.log('rendered (hbs) -------') 137 | console.log(file.content) 138 | next(null, file); 139 | })) 140 | .pipe(app.renderFile('tmpl')) 141 | .pipe(through.obj(function(file, enc, next) { 142 | console.log('rendered (tmpl) -------') 143 | console.log(file.content) 144 | next(null, file); 145 | })) 146 | .on('error', cb) 147 | .on('data', function(file) { 148 | files.push(file); 149 | }) 150 | .on('end', function() { 151 | assert(typeof files[0].fn, 'function'); 152 | assert.equal(typeof files[1].fn, 'function'); 153 | assert.equal(typeof files[2].fn, 'function'); 154 | cb(); 155 | }); 156 | }); 157 | 158 | it('should compile views from src with the engine passed on the opts', function(cb) { 159 | var stream = app.src(cwd('*.hbs')); 160 | var files = []; 161 | 162 | stream.pipe(app.compileFile({engine: '*'})) 163 | .on('error', cb) 164 | .on('data', function(file) { 165 | files.push(file); 166 | }) 167 | .on('end', function() { 168 | assert.equal(typeof files[0].fn, 'function'); 169 | assert.equal(typeof files[1].fn, 'function'); 170 | assert.equal(typeof files[2].fn, 'function'); 171 | cb(); 172 | }); 173 | }); 174 | 175 | it('should use the context passed on the opts', function(cb) { 176 | var stream = app.src(cwd('*.hbs')); 177 | var files = []; 178 | 179 | stream.pipe(app.compileFile({a: {title: 'foo'}})) 180 | .on('error', cb) 181 | .on('data', function(file) { 182 | files.push(file); 183 | }) 184 | .on('end', function() { 185 | assert.equal(typeof files[0].fn, 'function'); 186 | assert.equal(typeof files[1].fn, 'function'); 187 | assert.equal(typeof files[2].fn, 'function'); 188 | cb(); 189 | }); 190 | }); 191 | 192 | it('should support noop engines', function(cb) { 193 | var stream = app.src(path.join(__dirname, '.*')); 194 | var files = []; 195 | 196 | app.engine('noop', function(view, opts, next) { 197 | next(null, view); 198 | }); 199 | 200 | stream.pipe(app.compileFile()) 201 | .on('error', cb) 202 | .on('finish', cb); 203 | }); 204 | 205 | it('should pass files through when `engineStrict` is false', function(cb) { 206 | var stream = app.src(path.join(__dirname, '.*')); 207 | 208 | app.option('engineStrict', false); 209 | stream.pipe(app.compileFile()) 210 | .on('error', cb) 211 | .on('finish', cb); 212 | }); 213 | 214 | it('should compile the files in a collection', function(cb) { 215 | var files = []; 216 | app.toStream('files') 217 | .pipe(app.compileFile()) 218 | .on('error', cb) 219 | .on('data', function(file) { 220 | assert(file); 221 | assert(file.path); 222 | assert(file, 'function'); 223 | files.push(file); 224 | }) 225 | .on('end', function() { 226 | assert.equal(typeof files[0].fn, 'function'); 227 | assert.equal(typeof files[1].fn, 'function'); 228 | assert.equal(typeof files[2].fn, 'function'); 229 | assert.equal(files.length, 3); 230 | cb(); 231 | }); 232 | }); 233 | }); 234 | 235 | describe('app.compileFile()', function() { 236 | beforeEach(function(cb) { 237 | app = new Assemble() 238 | .use(compileFile()) 239 | 240 | var hbs = require('engine-handlebars'); 241 | hbs.Handlebars.helpers = {}; 242 | 243 | app.engine('hbs', hbs); 244 | app.engine('tmpl', require('engine-base')); 245 | app.create('partials', {viewType: 'partial'}); 246 | app.partial('button', {content: 'Click me!'}); 247 | 248 | app.data({title: 'foo'}); 249 | cb(); 250 | }); 251 | 252 | it('should compile views with the engine specified on arguments', function(cb) { 253 | var stream = app.src(cwd('engines/*.hbs')); 254 | var files = []; 255 | 256 | stream.pipe(app.compileFile('tmpl')) 257 | .on('error', cb) 258 | .on('data', function(file) { 259 | files.push(file); 260 | }) 261 | .on('end', function() { 262 | assert.equal(typeof files[0].fn, 'function'); 263 | assert.equal(typeof files[1].fn, 'function'); 264 | assert.equal(typeof files[2].fn, 'function'); 265 | cb(); 266 | }); 267 | }); 268 | 269 | it('should compile with the same engine multiple times', function(cb) { 270 | var stream = app.src(cwd('engines/*.hbs')); 271 | var files = []; 272 | 273 | stream 274 | .pipe(app.compileFile('tmpl')) 275 | .pipe(app.compileFile('tmpl')) 276 | .pipe(app.compileFile('tmpl')) 277 | .on('error', cb) 278 | .on('data', function(file) { 279 | files.push(file); 280 | }) 281 | .on('end', function() { 282 | assert.equal(typeof files[0].fn, 'function'); 283 | assert.equal(typeof files[1].fn, 'function'); 284 | assert.equal(typeof files[2].fn, 'function'); 285 | cb(); 286 | }); 287 | }); 288 | 289 | it('should compile a template with multiple duplicate partials', function(cb) { 290 | var files = []; 291 | app.src(cwd('multiple/page.hbs')) 292 | .pipe(app.compileFile('hbs')) 293 | .on('error', cb) 294 | .on('data', function(file) { 295 | files.push(file); 296 | }) 297 | .on('end', function() { 298 | assert.equal(typeof files[0].fn, 'function'); 299 | cb(); 300 | }); 301 | }); 302 | 303 | it('should compile views with multiple calls to compileFile', function(cb) { 304 | var stream = app.src(cwd('engines/*.hbs')); 305 | var files = []; 306 | 307 | stream 308 | .pipe(app.compileFile('tmpl')) 309 | .pipe(app.compileFile('hbs')) 310 | .on('error', cb) 311 | .on('data', function(file) { 312 | files.push(file); 313 | }) 314 | .on('end', function() { 315 | assert.equal(typeof files[0].fn, 'function'); 316 | assert.equal(typeof files[1].fn, 'function'); 317 | assert.equal(typeof files[2].fn, 'function'); 318 | 319 | assert.equal(typeof files[0].fn, 'function'); 320 | assert.equal(typeof files[1].fn, 'function'); 321 | assert.equal(typeof files[2].fn, 'function'); 322 | cb(); 323 | }); 324 | }); 325 | 326 | it('should compile views with multiple calls to compileFile and locals', function(cb) { 327 | var stream = app.src(cwd('engines/a.hbs')); 328 | var files = []; 329 | 330 | stream 331 | .pipe(app.compileFile('tmpl', {title: 'foo'})) 332 | .on('error', cb) 333 | .pipe(app.compileFile('hbs', {title: 'bar'})) 334 | .on('error', cb) 335 | .on('data', function(file) { 336 | files.push(file); 337 | }) 338 | .on('end', function() { 339 | assert.equal(typeof files[0].fn, 'function'); 340 | assert.equal(typeof files[0].fn, 'function'); 341 | cb(); 342 | }); 343 | }); 344 | }); 345 | 346 | --------------------------------------------------------------------------------