Skip to content

Instantly share code, notes, and snippets.

@manuhabitela
Created December 3, 2017 17:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save manuhabitela/66c90d80c9bb471419b1a94efa3281e2 to your computer and use it in GitHub Desktop.
Save manuhabitela/66c90d80c9bb471419b1a94efa3281e2 to your computer and use it in GitHub Desktop.
Metalsmith plugin to transform one JSON array to multiple "files" in the metalsmith chain
const _ = require('lodash');
const path = require('path');
/**
* metalsmith plugin that transforms one JSON array to multiple "files" in the metalsmith chain
*
* A JSON file is taken by the plugin if a ".json" extension is detected + it has a "type: collection" metadata.
* Each object in the JSON array must at least have a "path" key to generate the fake file path.
* All other properties are set on the file object.
*
* for example, if you have a "examples.json" file containing:
*
* ---
* type: collection
* ---
* [
* {"contents": "This is some content", "path": "example-1.html"},
* {"contents": "This is some other content with meta data", "date": "2016-01-01", "path": "example-2"}
* ]
*
* the metalsmith files object will be filled with:
*
* {
* "examples/example-1.html": {
* "contents": "This is some content"
* },
* "examples/example-2.txt": {
* "contents": "This is some other content with meta data",
* "date": "2016-01-01"
* }
* }
*/
module.exports = () => (files, metalsmith, done) => {
setImmediate(done);
let cylonFiles = {}; // these look like files. But they aren't.
Object.keys(files).forEach((file) => {
const data = files[file];
// only check json file that are set as "collection"
if (path.extname(file) !== '.json' || data.type !== 'collection') {
return true;
}
const collectionName = path.basename(file, '.json');
const json = JSON.parse(data.contents);
// add our data to a temporary object to prevent loop issues
_.extend(cylonFiles, getFilesObjectForCollection(json, collectionName));
// do not keep the original JSON in the metalsmith chain
delete files[file];
});
_.extend(files, cylonFiles);
};
function getFilesObjectForCollection(json, collectionName) {
const result = {};
_.forEach(json, (line) => {
const extension = path.extname(line.path) ? '' : '.txt';
const filepath = path.join(collectionName, line.path + extension);
delete line.path;
result[filepath] = line;
});
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment