Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

metalsmith-layouts

Package Overview
Dependencies
Maintainers
1
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

metalsmith-layouts - npm Package Compare versions

Comparing version 1.8.1 to 2.0.0

.github/ISSUE_TEMPLATE.md

242

lib/index.js

@@ -1,176 +0,118 @@

/**
* Dependencies
*/
var consolidate = require('consolidate');
var debug = require('debug')('metalsmith-layouts');
var each = require('async').each;
var extend = require('extend');
var omit = require('lodash.omit');
var path = require('path');
const match = require('multimatch');
const path = require('path');
const isUtf8 = require('is-utf8');
const getTransformer = require('./get-transformer');
/**
* Helpers
* Resolves layouts, in the following order:
* 1. Layouts in the frontmatter
* 2. Skips file if layout: false in frontmatter
* 3. Default layout in the settings
*/
var check = require('./helpers/check');
var readPartials = require('./helpers/read-partials');
/**
* Expose `plugin`.
*/
module.exports = plugin;
function getLayout({ file, settings }) {
if (file.layout || file.layout === false) {
return file.layout;
}
/**
* Settings
*
* Options supported by metalsmith-layouts
*/
var settings = [
'default',
'directory',
'engine',
'partials',
'partialExtension',
'pattern',
'rename',
'exposeConsolidate'
];
return settings.default;
}
/**
* Metalsmith plugin to run files through any layout in a layout `dir`.
*
* @param {String or Object} options
* @property {String} default (optional)
* @property {String} directory (optional)
* @property {String} engine
* @property {String} partials (optional)
* @property {String} partialExtension (optional)
* @property {String} pattern (optional)
* @property {Boolean} rename (optional)
* @return {Function}
* Engine, renders file with the appropriate layout
*/
function plugin(opts){
/**
* Init
*/
opts = opts || {};
// Accept string option to specify the engine
if (typeof opts === 'string') {
opts = {engine: opts};
}
function render({ file, metadata, settings, metalsmith }) {
return new Promise(resolve => {
const layout = getLayout({ file, settings });
const extension = layout.split('.').pop();
// An engine should be specified
if (!opts.engine) {
throw new Error('"engine" option required');
}
// Stringify file contents
// eslint-disable-next-line no-param-reassign
file.contents = file.contents.toString();
// Throw an error for unsupported engines or typos
if (!consolidate[opts.engine]) {
throw new Error('Unknown template engine: "' + opts.engine + '"');
}
const transform = getTransformer(extension);
const locals = Object.assign({}, metadata, file);
const layoutPath = path.join(metalsmith.path(settings.directory), layout);
if (typeof opts.exposeConsolidate === 'function') {
opts.exposeConsolidate(consolidate.requires)
}
// Transform the contents
// eslint-disable-next-line no-param-reassign
file.contents = transform.renderFile(layoutPath, settings.engineOptions, locals).body;
// Map options to local variables
var def = opts.default;
var dir = opts.directory || 'layouts';
var engine = opts.engine;
var partialExtension = opts.partialExtension;
var partials = opts.partials;
var pattern = opts.pattern;
var rename = opts.rename;
// Update file with results
// eslint-disable-next-line no-param-reassign
file.contents = Buffer.from(file.contents);
return resolve();
});
}
// Move all unrecognised options to params
var params = omit(opts, settings);
/**
* Validate, checks whether a file should be processed
*/
/**
* Main plugin function
*/
return function(files, metalsmith, done){
var metadata = metalsmith.metadata();
var matches = {};
var templates = {};
function validate({ file, settings }) {
const layout = getLayout({ file, settings });
/**
* Process any partials and pass them to consolidate as a partials object
*/
if (partials) {
if (typeof partials === 'string') {
params.partials = readPartials(partials, partialExtension, dir, metalsmith);
} else {
params.partials = partials;
}
}
// Files without a layout cannot be processed
if (!layout) {
return false;
}
/**
* Stringify files that pass the check, pass to matches
*/
Object.keys(files).forEach(function(file){
if (!check(files, file, pattern, def)) {
return;
}
// Layouts without an extension cannot be processed
if (!layout.includes('.')) {
return false;
}
debug('stringifying file: %s', file);
var data = files[file];
data.contents = data.contents.toString();
var template = metalsmith.path(dir, data.layout || def);
if (!templates[template]) {
debug('found new template: %s', template);
templates[template] = file;
} else {
matches[file] = data;
}
});
// Files that are not utf8 are ignored
if (!isUtf8(file.contents)) {
return false;
}
/**
* Render files
*/
function convert(file, done){
debug('converting file: %s', file);
var data = files[file];
// Files without an applicable jstransformer are ignored
const extension = layout.split('.').pop();
return getTransformer(extension);
}
// 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];
/**
* Plugin, the main plugin used by metalsmith
*/
// 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);
}
module.exports = options => (files, metalsmith, done) => {
const metadata = metalsmith.metadata();
const defaults = {
pattern: '**',
directory: 'layouts',
engineOptions: {}
};
const settings = Object.assign({}, defaults, options);
render(str, clone, function(err, str){
if (err) {
return done(err);
}
// Check whether the pattern option is valid
if (!(typeof settings.pattern === 'string' || Array.isArray(settings.pattern))) {
done(new Error('invalid pattern, the pattern option should be a string or array.'));
}
data.contents = new Buffer(str);
debug('converted file: %s', file);
// Filter files by the pattern
const matchedFiles = match(Object.keys(files), settings.pattern);
files[file] = data;
done();
});
}
// Filter files by validity
const validFiles = matchedFiles.filter(filename => validate({ file: files[filename], settings }));
/**
* Render all matched files.
*/
function renderFiles(err) {
if (err) {
return done(err);
}
each(Object.keys(matches), convert, done);
}
// Let the user know when there are no files to process, usually caused by missing jstransformer
if (validFiles.length === 0) {
done(new Error('no files to process, check whether you have a jstransformer installed.'));
}
// Do a first pass to load templates into the consolidate cache.
each(templates, convert, renderFiles);
};
}
// Map all files that should be processed to an array of promises and call done when finished
Promise.all(
validFiles.map(filename =>
render({
file: files[filename],
metadata,
settings,
metalsmith
})
)
)
.then(() => done())
.catch(/* istanbul ignore next */ error => done(error));
};
{
"name": "metalsmith-layouts",
"author": "superwolff <superwolff@superwolff.nl> (http://superwolff.nl/)",
"author": "ismay",
"description": "A metalsmith plugin for layouts.",
"repository": "git://github.com/superwolff/metalsmith-layouts.git",
"version": "1.8.1",
"license": "MIT",
"main": "lib/index.js",
"name": "metalsmith-layouts",
"repository": "git://github.com/ismay/metalsmith-layouts.git",
"version": "2.0.0",
"scripts": {
"test": "mocha --reporter spec"
"precommit": "lint-staged",
"lint:js": "eslint 'lib/**/*.js'",
"lint:prettier": "prettier --list-different 'lib/**/*.js'",
"test": "jest",
"test:coverage": "jest --coverage && cat ./coverage/lcov.info | coveralls"
},
"dependencies": {
"async": "^1.3.0",
"consolidate": "^0.14.0",
"debug": "^2.2.0",
"extend": "^3.0.0",
"fs-readdir-recursive": "^1.0.0",
"is-utf8": "^0.2.0",
"lodash.omit": "^4.0.2",
"multimatch": "^2.0.0"
"jest": {
"collectCoverageFrom": [
"lib/*.js"
]
},
"greenkeeper": {
"ignore": [
"eslint",
"eslint-plugin-import"
]
},
"devDependencies": {
"assert-dir-equal": "^1.0.1",
"handlebars": "^4.0.2",
"metalsmith": "^2.0.1",
"mocha": "^2.2.5",
"swig": "^1.4.2"
"assert-dir-equal": "^1.1.0",
"coveralls": "^3.0.0",
"eslint": "^4.8.0",
"eslint-config-airbnb-base": "^12.0.2",
"eslint-config-prettier": "^2.9.0",
"eslint-plugin-import": "^2.7.0",
"husky": "^0.14.3",
"jest": "^22.0.4",
"jstransformer-handlebars": "^1.0.0",
"lint-staged": "^6.0.0",
"metalsmith": "^2.3.0",
"prettier": "^1.9.2",
"rimraf": "^2.6.2"
},
"dependencies": {
"inputformat-to-jstransformer": "^1.2.1",
"is-utf8": "^0.2.1",
"jstransformer": "^1.0.0",
"multimatch": "^2.1.0"
}
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc