From 8f9d735873555c5f955b55f5e99d8c4c341512ee Mon Sep 17 00:00:00 2001 From: Frederik Dudzik Date: Wed, 6 Jul 2016 00:19:54 +0200 Subject: [PATCH] expose render function --- Readme.md | 34 +++++++++++++++--- lib/helpers/renderer.js | 39 +++++++++++++++++++++ lib/index.js | 76 +++++++++++++++++++++++------------------ 3 files changed, 112 insertions(+), 37 deletions(-) create mode 100644 lib/helpers/renderer.js diff --git a/Readme.md b/Readme.md index 013fae9..b726618 100644 --- a/Readme.md +++ b/Readme.md @@ -85,6 +85,7 @@ You can pass options to `metalsmith-layouts` with the [Javascript API](https://g * [partials](#partials): directory for the partials (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) +* [renderer](#renderer): apply a custom render function (optional) ### 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`. -### exposeConsolidate +### renderer 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 // ... .use(layout('swig', { - exposeConsolidate: function(requires) { - // your code here + renderer: function(engine) { + 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); + }); + } } })) // ... diff --git a/lib/helpers/renderer.js b/lib/helpers/renderer.js new file mode 100644 index 0000000..46498a2 --- /dev/null +++ b/lib/helpers/renderer.js @@ -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); + }); + } +} diff --git a/lib/index.js b/lib/index.js index 7ec72d3..0a8d571 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,18 +1,18 @@ /** * Dependencies */ -var consolidate = require('consolidate'); -var debug = require('debug')('metalsmith-layouts'); -var each = require('async').each; +var debug = require('debug')('metalsmith-layouts'); +var each = require('async').each; var extend = require('extend'); -var omit = require('lodash.omit'); -var path = require('path'); +var omit = require('lodash.omit'); +var path = require('path'); /** * Helpers */ -var check = require('./helpers/check'); +var check = require('./helpers/check'); var readPartials = require('./helpers/read-partials'); +var renderer = require('./helpers/renderer'); /** * Expose `plugin`. @@ -31,7 +31,7 @@ var settings = [ 'partials', 'pattern', 'rename', - 'exposeConsolidate' + 'renderer', ]; /** @@ -44,6 +44,7 @@ var settings = [ * @property {String} partials (optional) * @property {String} pattern (optional) * @property {Boolean} rename (optional) + * @property {Function} renderer (optional) * @return {Function} */ function plugin(opts){ @@ -62,22 +63,21 @@ function plugin(opts){ throw new Error('"engine" option required'); } - // Throw an error for unsupported engines or typos - if (!consolidate[opts.engine]) { - throw new Error('Unknown template engine: "' + opts.engine + '"'); - } - - if (typeof opts.exposeConsolidate === 'function') { - opts.exposeConsolidate(consolidate.requires) + // An renderer for the layout can be added + var render; + if (typeof opts.renderer === 'function') { + render = opts.renderer(opts.engine); + } else { + render = renderer(opts.engine); } // Map options to local variables - var def = opts.default; - var dir = opts.directory || 'layouts'; - var engine = opts.engine; + var def = opts.default; + var dir = opts.directory || 'layouts'; + var engine = opts.engine; var partials = opts.partials; - var pattern = opts.pattern; - var rename = opts.rename; + var pattern = opts.pattern; + var rename = opts.rename; // Move all unrecognised options to params var params = omit(opts, settings); @@ -123,30 +123,40 @@ function plugin(opts){ // Deep clone params (by passing 'true') var clonedParams = extend(true, {}, params); - var clone = extend({}, clonedParams, metadata, data); - var str = metalsmith.path(dir, data.layout || def); - var render = consolidate[engine]; + var paramsToPass = extend({}, clonedParams, metadata, data); + var layoutPath = metalsmith.path(dir, data.layout || def); - // Rename file if necessary - var fileInfo; - if (rename) { - delete files[file]; - fileInfo = path.parse(file); - file = path.join(fileInfo.dir, fileInfo.name + '.html'); - debug('renamed file to: %s', file); + var renameFile = function(data){ + // Rename file if necessary + var fileInfo; + if (rename) { + delete files[file]; + fileInfo = path.parse(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) { return done(err); } - data.contents = new Buffer(str); debug('converted file: %s', file); - files[file] = data; + data.contents = new Buffer(result); + + renameFile(data); done(); - }); + } + + render(layoutPath, paramsToPass, handleRenderResult); } /**