expose render function

This commit is contained in:
Frederik Dudzik 2016-07-06 00:19:54 +02:00
parent 4002b654be
commit 8f9d735873
3 changed files with 112 additions and 37 deletions

View file

@ -85,6 +85,7 @@ You can pass options to `metalsmith-layouts` with the [Javascript API](https://g
* [partials](#partials): directory for the partials (optional) * [partials](#partials): directory for the partials (optional)
* [pattern](#pattern): only files that match this pattern will be processed (optional) * [pattern](#pattern): only files that match this pattern will be processed (optional)
* [rename](#rename): change the file extension of processed files to `.html` (optional) * [rename](#rename): change the file extension of processed files to `.html` (optional)
* [renderer](#renderer): apply a custom render function (optional)
### engine ### engine
@ -192,16 +193,41 @@ Change the file extension of processed files to `.html` (optional). This option
Would rename the extensions of all processed files to `.html`. Would rename the extensions of all processed files to `.html`.
### exposeConsolidate ### renderer
Not available over the `metalsmith.json` file. Not available over the `metalsmith.json` file.
Exposes Consolidate.requires as a function. Exposes the renderer as a function.
You use this if you want to access consolidate.requires.
```js ```js
// ... // ...
.use(layout('swig', { .use(layout('swig', {
exposeConsolidate: function(requires) { renderer: function(engine) {
// your code here var consolidate = require('consolidate');
var nunjucks = require('nunjucks');
var render = consolidate[engine];
if (!consolidate[engine]) {
throw new Error('Unknown template engine: "' + engine + '"');
}
// add nunjucks to requires so filters can be
// added and the same instance will be used inside the render method
consolidate.requires.nunjucks = nunjucks.configure();
consolidate.requires.nunjucks.addFilter('foo', function () {
return 'bar';
});
return function render(layoutPath, params, done) {
render(layoutPath, params, function(err, result){
if (err) {
return done(err);
}
done(err, result);
});
}
} }
})) }))
// ... // ...

39
lib/helpers/renderer.js Normal file
View file

@ -0,0 +1,39 @@
/**
* Dependencies
*/
var consolidate = require('consolidate');
/**
* Expose `renderer`
*/
module.exports = renderer;
/**
* Helper for creating a render function.
*
* @param {String} engine
* @return {Function}
*/
function renderer (engine) {
if (!consolidate[engine]) {
throw new Error('Unknown template engine: "' + engine + '"');
}
var render = consolidate[engine];
/**
* A function that renders a layout
*
* @param {String} engine
* @return {Function}
*/
return function renderFn (layoutPath, params, done) {
render(layoutPath, params, function(err, result) {
if (err) {
return done(err);
}
done(err, result);
});
}
}

View file

@ -1,18 +1,18 @@
/** /**
* Dependencies * Dependencies
*/ */
var consolidate = require('consolidate'); var debug = require('debug')('metalsmith-layouts');
var debug = require('debug')('metalsmith-layouts'); var each = require('async').each;
var each = require('async').each;
var extend = require('extend'); var extend = require('extend');
var omit = require('lodash.omit'); var omit = require('lodash.omit');
var path = require('path'); var path = require('path');
/** /**
* Helpers * Helpers
*/ */
var check = require('./helpers/check'); var check = require('./helpers/check');
var readPartials = require('./helpers/read-partials'); var readPartials = require('./helpers/read-partials');
var renderer = require('./helpers/renderer');
/** /**
* Expose `plugin`. * Expose `plugin`.
@ -31,7 +31,7 @@ var settings = [
'partials', 'partials',
'pattern', 'pattern',
'rename', 'rename',
'exposeConsolidate' 'renderer',
]; ];
/** /**
@ -44,6 +44,7 @@ var settings = [
* @property {String} partials (optional) * @property {String} partials (optional)
* @property {String} pattern (optional) * @property {String} pattern (optional)
* @property {Boolean} rename (optional) * @property {Boolean} rename (optional)
* @property {Function} renderer (optional)
* @return {Function} * @return {Function}
*/ */
function plugin(opts){ function plugin(opts){
@ -62,22 +63,21 @@ function plugin(opts){
throw new Error('"engine" option required'); throw new Error('"engine" option required');
} }
// Throw an error for unsupported engines or typos // An renderer for the layout can be added
if (!consolidate[opts.engine]) { var render;
throw new Error('Unknown template engine: "' + opts.engine + '"'); if (typeof opts.renderer === 'function') {
} render = opts.renderer(opts.engine);
} else {
if (typeof opts.exposeConsolidate === 'function') { render = renderer(opts.engine);
opts.exposeConsolidate(consolidate.requires)
} }
// Map options to local variables // Map options to local variables
var def = opts.default; var def = opts.default;
var dir = opts.directory || 'layouts'; var dir = opts.directory || 'layouts';
var engine = opts.engine; var engine = opts.engine;
var partials = opts.partials; var partials = opts.partials;
var pattern = opts.pattern; var pattern = opts.pattern;
var rename = opts.rename; var rename = opts.rename;
// Move all unrecognised options to params // Move all unrecognised options to params
var params = omit(opts, settings); var params = omit(opts, settings);
@ -123,30 +123,40 @@ function plugin(opts){
// Deep clone params (by passing 'true') // Deep clone params (by passing 'true')
var clonedParams = extend(true, {}, params); var clonedParams = extend(true, {}, params);
var clone = extend({}, clonedParams, metadata, data); var paramsToPass = extend({}, clonedParams, metadata, data);
var str = metalsmith.path(dir, data.layout || def); var layoutPath = metalsmith.path(dir, data.layout || def);
var render = consolidate[engine];
// Rename file if necessary var renameFile = function(data){
var fileInfo; // Rename file if necessary
if (rename) { var fileInfo;
delete files[file]; if (rename) {
fileInfo = path.parse(file); delete files[file];
file = path.join(fileInfo.dir, fileInfo.name + '.html'); fileInfo = path.parse(file);
debug('renamed file to: %s', file); file = path.join(fileInfo.dir, fileInfo.name + '.html');
debug('renamed file to: %s', file);
files[file] = data;
}
} }
render(str, clone, function(err, str){ /**
* is called after a layout is renderd
* renames file if neccessary
* applys the render result to the new file
*/
var handleRenderResult = function(err, result) {
if (err) { if (err) {
return done(err); return done(err);
} }
data.contents = new Buffer(str);
debug('converted file: %s', file); debug('converted file: %s', file);
files[file] = data; data.contents = new Buffer(result);
renameFile(data);
done(); done();
}); }
render(layoutPath, paramsToPass, handleRenderResult);
} }
/** /**