canner-core
Version:
A static webpage generator based on template engines, which aimed to deal with the maintenance difficulty between data and webpages.
175 lines (146 loc) • 4.97 kB
JavaScript
var path = require('path');
var Q = require('q');
var _ = require('lodash');
var fs = require('fs');
var stage = require('node-stage');
var watch = require('watch');
var httpServer = require('http-server');
var chalk = require('chalk');
var generator = require("./generator");
/*
* Build
* Build a canner from a canner.json
* @param {string | Object} cannerJson - source to canner.json, default ./canner.json
* or a object, containing canner.json settings
* @param {object} options - options
* @param {boolean} watchOpt - whether watch the folder or not
*/
module.exports = function(cannerJson, options, watchOpt) {
if(_.isString(cannerJson))
var cannerParentDir= path.join(process.cwd(), cannerJson, '..');
else
var cannerParentDir= process.cwd();
// output is the dir path where content will be generated
var output = options.output || cannerParentDir;
// serveDir
var serveDir = options.serve || cannerParentDir;
// template engine
var tmp_engine = options.engine || 'hbs';
// cannerJson default to local dir path
cannerJson = cannerJson || './canner.json';
// see if we need to open localhost, for convinience
if (serveDir !== undefined && options.localhost) {
var server = httpServer.createServer();
var host = '127.0.0.1';
var port = options.port || 4000;
server.listen(port, host);
stage.success('Serving "' + serveDir + '" at http://localhost:' + port);
}
// if watch needed, start file watch
if (watchOpt) {
_watchFs(serveDir, cannerJson, output, options);
stage.process('Watching files under \'' + chalk.cyan(serveDir) + '\'...');
}
// generate
stage.process('Starting \'' + chalk.cyan('build') + '\'...');
return generator.build(output, cannerJson, tmp_engine, options);
};
var _regenerateDoc = function(monitor, dir, cannerJson, output, options, filter) {
var rebuildAndWatch= function (cannerJson) {
var tmp_engine = options.engine || 'hbs';
var buildPromise= generator.build(output, cannerJson, tmp_engine, options);
// if watch callback exist
if(options.watchCallback)
buildPromise.then(options.watchCallback);
// catch error
buildPromise.catch(function(err) {
stage.error(err);
});
// watch again
_watchFs(dir, cannerJson, output, options);
};
// remove all listeners
monitor.removeAllListeners();
// reload settings
if(!options.reloader)
rebuildAndWatch(cannerJson);
else
Q.when(options.reloader()).then(function (cannerJson) {
if(filter)
cannerJson= _.filter(cannerJson, filter);
rebuildAndWatch(cannerJson);
});
}
var _watchFs = function(dir, cannerJson, output, options) {
var filter= function (f) {
var filename;
if(_.isString(cannerJson)){
try {
var load = JSON.parse(fs.readFileSync(cannerJson, 'utf8'));
} catch (e){
// not a json file a commonjs file.
var load = fs.readFileSync(cannerJson, 'utf8');
}
if(Object.prototype.toString.call(load)=='[object Array]') {
// if it is array then multi filename
var load = load.map(function(item) {
return item.filename || './index.html';
})
filename = load;
}else {
// an object, one item
filename = load.filename || './index.html';
filename = [filename];
}
}else{
filename= './canner.json';
filename = [filename];
}
var f_arr = filename.map(function(fname){
return path.join(output, fname)
})
// exclude filename in cannerJson
return (f_arr.indexOf(f) === -1);
}
dir = path.resolve(dir);
watch.createMonitor(dir, {filter: filter}, function(monitor) {
monitor.on("created", function(f, stat) {
// Handle new files
monitor.stop();
stage.process("File " + f + " have been created. ");
// filter
if(options.createFilter)
var filter= function (row) {
return options.createFilter(row, f, stat);
};
// generate
_regenerateDoc(monitor, dir, cannerJson, output, options, filter);
});
monitor.on("changed", function(f, curr, prev) {
// Handle file changes
monitor.stop();
stage.process("File " + f + " have been changed. ");
// filter
var filter;
if(options.changeFilter)
filter= function (row) {
return options.changeFilter(row, f, curr, prev);
};
// generate
_regenerateDoc(monitor, dir, cannerJson, output, options, filter);
});
monitor.on("removed", function(f, stat) {
// Handle removed files
monitor.stop();
stage.process("File " + f + " have been removed. ");
// filter
var filter;
if(options.removeFilter)
filter= function (row) {
return options.removeFilter(row, f, stat);
};
// generate
_regenerateDoc(monitor, dir, cannerJson, output, options, filter);
});
});
};