diff --git a/lib/index.js b/lib/index.js index 45793f1..8e62b62 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,4 +1,3 @@ - var debug = require('debug')('metalsmith-collections'); var extend = require('extend'); var multimatch = require('multimatch'); @@ -20,26 +19,25 @@ module.exports = plugin; * @return {Function} */ -function plugin(opts, globalOpts){ +function plugin(opts, globalOpts) { opts = normalize(opts); var keys = Object.keys(opts); var match = matcher(opts); - return function(files, metalsmith, done){ + return function(files, metalsmith, done) { var metadata = metalsmith.metadata(); /** * Find the files in each collection. */ - Object.keys(files).forEach(function(file){ + Object.keys(files).forEach(function(file) { debug('checking file: %s', file); var data = files[file]; + data.path = file; - data.path = file - - match(file, data).forEach(function(key){ - if (key && keys.indexOf(key) < 0){ + Object.keys(match(file, data)).forEach(function(key) { + if (key && keys.indexOf(key) < 0) { opts[key] = {}; keys.push(key); } @@ -53,7 +51,7 @@ function plugin(opts, globalOpts){ * Ensure that a default empty collection exists. */ - keys.forEach(function(key) { + Object.keys(keys).forEach(function(key) { metadata[key] = metadata[key] || []; }); @@ -61,8 +59,8 @@ function plugin(opts, globalOpts){ * Merge global options with collection options */ - keys.forEach(function(key){ - for(var gKey in globalOpts){ + keys.forEach(function(key) { + for (var gKey in globalOpts) { opts[key][gKey] = opts[key][gKey] || globalOpts[gKey]; } }); @@ -70,19 +68,18 @@ function plugin(opts, globalOpts){ /** * Sort the collections. */ - - keys.forEach(function(key){ + keys.forEach(function(key) { debug('sorting collection: %s', key); var settings = opts[key]; - var sort = settings.sortBy || (globalOpts.sortBy || 'date'); + var sort = settings.sortBy || 'date'; var col = metadata[key]; if ('function' == typeof sort) { col.sort(sort); } else { - col.sort(function(a, b){ - a = a[sort]; - b = b[sort]; + col.sort(function(a, b) { + a = (a.collection[key]) ? (a.collection[key][sort] || a[sort]) : a[sort]; + b = (b.collection[key]) ? (b.collection[key][sort] || b[sort]) : b[sort]; if (!a && !b) return 0; if (!a) return -1; if (!b) return 1; @@ -99,19 +96,19 @@ function plugin(opts, globalOpts){ * Add `next` and `previous` references and apply the `limit` option */ - keys.forEach(function(key){ + keys.forEach(function(key) { debug('referencing collection: %s', key); var settings = opts[key]; var col = metadata[key]; var last = col.length - 1; if (opts[key].limit && opts[key].limit < col.length) { - col = metadata[key] = col.slice(0, opts[key].limit); - last = opts[key].limit - 1; + col = metadata[key] = col.slice(0, opts[key].limit); + last = opts[key].limit - 1; } if (settings.refer === false) return; - col.forEach(function(file, i){ - if (0 != i) file.previous = col[i-1]; - if (last != i) file.next = col[i+1]; + col.forEach(function(file, i) { + if (0 != i) file.previous = col[i - 1]; + if (last != i) file.next = col[i + 1]; }); }); @@ -119,13 +116,15 @@ function plugin(opts, globalOpts){ * Add collection metadata */ - keys.forEach(function(key){ + keys.forEach(function(key) { debug('adding metadata: %s', key); var settings = opts[key]; var col = metadata[key]; col.metadata = (typeof settings.metadata === 'string') ? loadMetadata(settings.metadata) : - settings.metadata; + (settings.metadata || {}); + + Object.assign(col.metadata, globalOpts); }); /** @@ -133,7 +132,7 @@ function plugin(opts, globalOpts){ */ metadata.collections = {}; - keys.forEach(function(key){ + keys.forEach(function(key) { return metadata.collections[key] = metadata[key]; }); @@ -147,13 +146,17 @@ function plugin(opts, globalOpts){ * @param {Object} options */ -function normalize(options){ +function normalize(options) { options = options || {}; for (var key in options) { var val = options[key]; - if ('string' == typeof val) options[key] = { pattern: val }; - if (val instanceof Array) options[key] = { pattern: val }; + if ('string' == typeof val) options[key] = { + pattern: val + }; + if (val instanceof Array) options[key] = { + pattern: val + }; } return options; @@ -166,31 +169,44 @@ function normalize(options){ * @return {Function} */ -function matcher(cols){ +function matcher(cols) { var keys = Object.keys(cols); var matchers = {}; - keys.forEach(function(key){ + keys.forEach(function(key) { var opts = cols[key]; if (!opts.pattern) { return; } matchers[key] = { match: function(file) { - return multimatch(file, opts.pattern) + return multimatch(file, opts.pattern); } }; }); - return function(file, data){ + return function(file, data) { var matches = []; if (data.collection) { var collection = data.collection; - if (!Array.isArray(collection)) { - collection = [collection]; + let tmpCollection = {}; + + if (Array.isArray(collection)) { + for (let collItem of collection) { + tmpCollection[collItem] = {}; + } + } else if (collection.constructor === String) + tmpCollection[collection] = {}; + else if (collection instanceof Object) + tmpCollection = collection; + else { + collection = {}; } - collection.forEach(function(key){ + + collection = data.collection = tmpCollection; + + Object.keys(collection).forEach(function(key) { matches.push(key); if (key && keys.indexOf(key) < 0) { @@ -199,14 +215,13 @@ function matcher(cols){ }); } - for (var key in matchers){ + for (var key in matchers) { var m = matchers[key]; if (m.match(file).length) { matches.push(key); } } - data.collection = unique(matches); - return data.collection; + return data.collection || {}; }; }