You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3661 lines
108 KiB
3661 lines
108 KiB
// Generated by CoffeeScript 1.6.2
|
|
var Backbone, BasePlugin, CSON, Collection, DocPad, DocumentModel, ElementsCollection, EventEmitterEnhanced, Events, FileModel, FilesCollection, MetaCollection, Model, PluginLoader, QueryCollection, ScriptsCollection, StylesCollection, TaskGroup, View, ambi, balUtil, canihaz, eachr, extendr, pathUtil, queryEngine, safefs, typeChecker, util, _, _ref,
|
|
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
|
|
__hasProp = {}.hasOwnProperty,
|
|
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
|
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
|
|
__slice = [].slice;
|
|
|
|
pathUtil = require('path');
|
|
|
|
_ = require('lodash');
|
|
|
|
CSON = require('cson');
|
|
|
|
balUtil = require('bal-util');
|
|
|
|
extendr = require('extendr');
|
|
|
|
eachr = require('eachr');
|
|
|
|
typeChecker = require('typechecker');
|
|
|
|
ambi = require('ambi');
|
|
|
|
TaskGroup = require('taskgroup').TaskGroup;
|
|
|
|
safefs = require('safefs');
|
|
|
|
util = require('util');
|
|
|
|
canihaz = null;
|
|
|
|
EventEmitterEnhanced = balUtil.EventEmitterEnhanced;
|
|
|
|
_ref = require(__dirname + '/base'), queryEngine = _ref.queryEngine, Backbone = _ref.Backbone, Events = _ref.Events, Model = _ref.Model, Collection = _ref.Collection, View = _ref.View, QueryCollection = _ref.QueryCollection;
|
|
|
|
FileModel = require(__dirname + '/models/file');
|
|
|
|
DocumentModel = require(__dirname + '/models/document');
|
|
|
|
FilesCollection = require(__dirname + '/collections/files');
|
|
|
|
ElementsCollection = require(__dirname + '/collections/elements');
|
|
|
|
MetaCollection = require(__dirname + '/collections/meta');
|
|
|
|
ScriptsCollection = require(__dirname + '/collections/scripts');
|
|
|
|
StylesCollection = require(__dirname + '/collections/styles');
|
|
|
|
PluginLoader = require(__dirname + '/plugin-loader');
|
|
|
|
BasePlugin = require(__dirname + '/plugin');
|
|
|
|
/*
|
|
The DocPad Class
|
|
It extends the EventSystem from bal-util to provide system events
|
|
It allows us to support multiple instances of docpad at the same time
|
|
*/
|
|
|
|
|
|
DocPad = (function(_super) {
|
|
__extends(DocPad, _super);
|
|
|
|
DocPad.prototype.Events = Events;
|
|
|
|
DocPad.prototype.Model = Model;
|
|
|
|
DocPad.prototype.Collection = Collection;
|
|
|
|
DocPad.prototype.View = View;
|
|
|
|
DocPad.prototype.QueryCollection = QueryCollection;
|
|
|
|
DocPad.prototype.FileModel = FileModel;
|
|
|
|
DocPad.prototype.DocumentModel = DocumentModel;
|
|
|
|
DocPad.prototype.FilesCollection = FilesCollection;
|
|
|
|
DocPad.prototype.ElementsCollection = ElementsCollection;
|
|
|
|
DocPad.prototype.MetaCollection = MetaCollection;
|
|
|
|
DocPad.prototype.ScriptsCollection = ScriptsCollection;
|
|
|
|
DocPad.prototype.StylesCollection = StylesCollection;
|
|
|
|
DocPad.prototype.PluginLoader = PluginLoader;
|
|
|
|
DocPad.prototype.BasePlugin = BasePlugin;
|
|
|
|
DocPad.prototype.growlInstance = null;
|
|
|
|
DocPad.prototype.getGrowlInstance = function() {
|
|
var err;
|
|
|
|
if ((this.growlInstance != null) === false) {
|
|
if (this.getConfig().growl) {
|
|
try {
|
|
this.growlInstance = require('growl');
|
|
} catch (_error) {
|
|
err = _error;
|
|
this.growlInstance = false;
|
|
}
|
|
} else {
|
|
this.growlInstance = false;
|
|
}
|
|
}
|
|
return this.growlInstance;
|
|
};
|
|
|
|
DocPad.prototype.mixpanelInstance = null;
|
|
|
|
DocPad.prototype.getMixpanelInstance = function() {
|
|
var config, err, mixpanelToken, reportStatistics;
|
|
|
|
if ((this.mixpanelInstance != null) === false) {
|
|
config = this.getConfig();
|
|
reportStatistics = config.reportStatistics, mixpanelToken = config.mixpanelToken;
|
|
if ((reportStatistics != null) && (mixpanelToken != null)) {
|
|
if (reportStatistics && mixpanelToken) {
|
|
try {
|
|
this.mixpanelInstance = require('mixpanel').init(mixpanelToken);
|
|
} catch (_error) {
|
|
err = _error;
|
|
this.mixpanelInstance = false;
|
|
}
|
|
} else {
|
|
this.mixpanelInstance = false;
|
|
}
|
|
} else {
|
|
this.mixpanelInstance = null;
|
|
}
|
|
}
|
|
return this.mixpanelInstance;
|
|
};
|
|
|
|
DocPad.prototype.airbrakeInstance = null;
|
|
|
|
DocPad.prototype.getAirbrakeInstance = function() {
|
|
var airbrakeToken, config, err, reportErrors;
|
|
|
|
if ((this.airbrakeInstance != null) === false) {
|
|
config = this.getConfig();
|
|
airbrakeToken = config.airbrakeToken, reportErrors = config.reportErrors;
|
|
if (reportErrors === true && /win/.test(process.platform) === false) {
|
|
try {
|
|
this.airbrakeInstance = require('airbrake').createClientairbrakeToken();
|
|
} catch (_error) {
|
|
err = _error;
|
|
this.airbrakeInstance = false;
|
|
}
|
|
} else {
|
|
this.airbrakeInstance = false;
|
|
}
|
|
}
|
|
return this.airbrakeInstance;
|
|
};
|
|
|
|
DocPad.prototype.version = null;
|
|
|
|
DocPad.prototype.getVersion = function() {
|
|
return this.version;
|
|
};
|
|
|
|
DocPad.prototype.getProcessPlatform = function() {
|
|
return process.platform;
|
|
};
|
|
|
|
DocPad.prototype.getProcessVersion = function() {
|
|
return process.version.replace(/^v/, '');
|
|
};
|
|
|
|
DocPad.prototype.serverExpress = null;
|
|
|
|
DocPad.prototype.serverHttp = null;
|
|
|
|
DocPad.prototype.getServer = function(both) {
|
|
var serverExpress, serverHttp;
|
|
|
|
serverExpress = this.serverExpress, serverHttp = this.serverHttp;
|
|
if (both) {
|
|
return {
|
|
serverExpress: serverExpress,
|
|
serverHttp: serverHttp
|
|
};
|
|
} else {
|
|
return serverExpress;
|
|
}
|
|
};
|
|
|
|
DocPad.prototype.setServer = function(servers) {
|
|
this.serverExpress = servers.serverExpress;
|
|
return this.serverHttp = servers.serverHttp;
|
|
};
|
|
|
|
DocPad.prototype.loggerInstances = null;
|
|
|
|
DocPad.prototype.getLogger = function() {
|
|
var _ref1;
|
|
|
|
return (_ref1 = this.loggerInstances) != null ? _ref1.logger : void 0;
|
|
};
|
|
|
|
DocPad.prototype.getLoggers = function() {
|
|
return this.loggerInstances;
|
|
};
|
|
|
|
DocPad.prototype.setLoggers = function(loggers) {
|
|
if (this.loggerInstances) {
|
|
this.warn('Loggers have already been set');
|
|
} else {
|
|
this.loggerInstances = loggers;
|
|
}
|
|
return loggers;
|
|
};
|
|
|
|
DocPad.prototype.actionRunnerInstance = null;
|
|
|
|
DocPad.prototype.getActionRunner = function() {
|
|
return this.actionRunnerInstance;
|
|
};
|
|
|
|
DocPad.prototype.errorRunnerInstance = null;
|
|
|
|
DocPad.prototype.getErrorRunner = function() {
|
|
return this.errorRunnerInstance;
|
|
};
|
|
|
|
DocPad.prototype.trackRunnerInstance = null;
|
|
|
|
DocPad.prototype.getTrackRunner = function() {
|
|
return this.trackRunnerInstance;
|
|
};
|
|
|
|
DocPad.prototype.events = ['extendTemplateData', 'extendCollections', 'docpadLoaded', 'docpadReady', 'consoleSetup', 'generateBefore', 'populateCollections', 'generateAfter', 'parseBefore', 'parseAfter', 'contextualizeBefore', 'contextualizeAfter', 'renderBefore', 'render', 'renderDocument', 'renderAfter', 'writeBefore', 'writeAfter', 'serverBefore', 'serverExtend', 'serverAfter'];
|
|
|
|
DocPad.prototype.getEvents = function() {
|
|
return this.events;
|
|
};
|
|
|
|
DocPad.prototype.database = null;
|
|
|
|
DocPad.prototype.databaseCache = null;
|
|
|
|
DocPad.prototype.getDatabase = function() {
|
|
return this.database;
|
|
};
|
|
|
|
DocPad.prototype.getDatabaseCache = function() {
|
|
return this.databaseCache || this.database;
|
|
};
|
|
|
|
DocPad.prototype.filesByUrl = null;
|
|
|
|
DocPad.prototype.filesBySelector = null;
|
|
|
|
DocPad.prototype.filesByOutPath = null;
|
|
|
|
DocPad.prototype.blocks = null;
|
|
|
|
/* {
|
|
# A collection of meta elements
|
|
meta: null # Elements Collection
|
|
|
|
# A collection of script elements
|
|
scripts: null # Scripts Collection
|
|
|
|
# Collection of style elements
|
|
styles: null # Styles Collection
|
|
}
|
|
*/
|
|
|
|
|
|
DocPad.prototype.getBlock = function(name, clone) {
|
|
var block, classname;
|
|
|
|
block = this.blocks[name];
|
|
if (clone) {
|
|
classname = name[0].toUpperCase() + name.slice(1) + 'Collection';
|
|
block = new this[classname](block.models);
|
|
}
|
|
return block;
|
|
};
|
|
|
|
DocPad.prototype.setBlock = function(name, value) {
|
|
if (this.blocks[name] != null) {
|
|
this.blocks[name].destroy();
|
|
if (value) {
|
|
this.blocks[name] = value;
|
|
} else {
|
|
delete this.blocks[name];
|
|
}
|
|
} else {
|
|
this.blocks[name] = value;
|
|
}
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.getBlocks = function(blocks) {
|
|
this.blocks;
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.setBlocks = function(blocks) {
|
|
var name, value;
|
|
|
|
for (name in blocks) {
|
|
if (!__hasProp.call(blocks, name)) continue;
|
|
value = blocks[name];
|
|
this.setBlock(name, value);
|
|
}
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.collections = null;
|
|
|
|
/* {
|
|
# Documents collection
|
|
documents: null # QueryEngine Collection
|
|
|
|
# Files collection
|
|
files: null # QueryEngine Collection
|
|
|
|
# Layouts collection
|
|
layouts: null # QueryEngine Collection
|
|
}
|
|
*/
|
|
|
|
|
|
DocPad.prototype.getCollection = function(name) {
|
|
return this.collections[name];
|
|
};
|
|
|
|
DocPad.prototype.setCollection = function(name, value) {
|
|
if (this.collections[name] != null) {
|
|
this.collections[name].destroy();
|
|
if (value) {
|
|
this.collections[name] = value;
|
|
} else {
|
|
delete this.collections[name];
|
|
}
|
|
} else {
|
|
this.collections[name] = value;
|
|
}
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.getCollections = function() {
|
|
return this.collections;
|
|
};
|
|
|
|
DocPad.prototype.setCollections = function(collections) {
|
|
var name, value;
|
|
|
|
for (name in collections) {
|
|
if (!__hasProp.call(collections, name)) continue;
|
|
value = collections[name];
|
|
this.setCollection(name, value);
|
|
}
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.getFiles = function(query, sorting, paging) {
|
|
var files, key;
|
|
|
|
key = JSON.stringify({
|
|
query: query,
|
|
sorting: sorting,
|
|
paging: paging
|
|
});
|
|
files = this.getCollection(key);
|
|
if (!files) {
|
|
files = this.getDatabase().findAllLive(query, sorting, paging);
|
|
this.setCollection(key, files);
|
|
}
|
|
return files;
|
|
};
|
|
|
|
DocPad.prototype.getFile = function(query, sorting, paging) {
|
|
var file;
|
|
|
|
file = this.getDatabase().findOne(query, sorting, paging);
|
|
return file;
|
|
};
|
|
|
|
DocPad.prototype.getFilesAtPath = function(path, sorting, paging) {
|
|
var files, query;
|
|
|
|
query = {
|
|
$or: [
|
|
{
|
|
relativePath: {
|
|
$startsWith: path
|
|
}
|
|
}, {
|
|
fullPath: {
|
|
$startsWith: path
|
|
}
|
|
}
|
|
]
|
|
};
|
|
files = this.getFiles(query, sorting, paging);
|
|
return files;
|
|
};
|
|
|
|
DocPad.prototype.getFileAtPath = function(path, sorting, paging) {
|
|
var file;
|
|
|
|
file = this.getDatabase().fuzzyFindOne(path, sorting, paging);
|
|
return file;
|
|
};
|
|
|
|
DocPad.prototype.getFileByUrl = function(url, opts) {
|
|
var file, _ref1;
|
|
|
|
if (opts == null) {
|
|
opts = {};
|
|
}
|
|
if ((_ref1 = opts.collection) == null) {
|
|
opts.collection = this.getDatabase();
|
|
}
|
|
file = opts.collection.get(this.filesByUrl[url]);
|
|
return file;
|
|
};
|
|
|
|
DocPad.prototype.getFileBySelector = function(selector, opts) {
|
|
var file, _ref1;
|
|
|
|
if (opts == null) {
|
|
opts = {};
|
|
}
|
|
if ((_ref1 = opts.collection) == null) {
|
|
opts.collection = this.getDatabase();
|
|
}
|
|
file = opts.collection.get(this.filesBySelector[selector]);
|
|
if (!file) {
|
|
file = opts.collection.fuzzyFindOne(selector);
|
|
if (file) {
|
|
this.filesBySelector[selector] = file.id;
|
|
}
|
|
}
|
|
return file;
|
|
};
|
|
|
|
DocPad.prototype.skeletonsCollection = null;
|
|
|
|
DocPad.prototype.getSkeletons = function(next) {
|
|
var docpad, locale;
|
|
|
|
docpad = this;
|
|
locale = this.getLocale();
|
|
if (this.skeletonsCollection != null) {
|
|
return next(null, this.skeletonsCollection);
|
|
}
|
|
this.skeletonsCollection = new Collection();
|
|
this.skeletonsCollection.comparator = queryEngine.generateComparator({
|
|
position: 1,
|
|
name: 1
|
|
});
|
|
this.getExchange(function(err, exchange) {
|
|
var index, skeleton, skeletonKey, _ref1, _ref2, _ref3, _ref4;
|
|
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
index = 0;
|
|
_ref1 = exchange.skeletons;
|
|
for (skeletonKey in _ref1) {
|
|
if (!__hasProp.call(_ref1, skeletonKey)) continue;
|
|
skeleton = _ref1[skeletonKey];
|
|
if ((_ref2 = skeleton.id) == null) {
|
|
skeleton.id = skeletonKey;
|
|
}
|
|
if ((_ref3 = skeleton.name) == null) {
|
|
skeleton.name = skeletonKey;
|
|
}
|
|
if ((_ref4 = skeleton.position) == null) {
|
|
skeleton.position = index;
|
|
}
|
|
docpad.skeletonsCollection.add(new Model(skeleton));
|
|
++index;
|
|
}
|
|
docpad.skeletonsCollection.add(new Model({
|
|
id: 'none',
|
|
name: locale.skeletonNoneName,
|
|
description: locale.skeletonNoneDescription,
|
|
position: Infinity
|
|
}));
|
|
return next(null, docpad.skeletonsCollection);
|
|
});
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.slowPlugins = null;
|
|
|
|
DocPad.prototype.loadedPlugins = null;
|
|
|
|
DocPad.prototype.exchange = null;
|
|
|
|
DocPad.prototype.corePath = pathUtil.join(__dirname, '..', '..');
|
|
|
|
DocPad.prototype.libPath = __dirname;
|
|
|
|
DocPad.prototype.mainPath = pathUtil.join(__dirname, 'docpad');
|
|
|
|
DocPad.prototype.packagePath = pathUtil.join(__dirname, '..', '..', 'package.json');
|
|
|
|
DocPad.prototype.localePath = pathUtil.join(__dirname, '..', '..', 'locale');
|
|
|
|
DocPad.prototype.debugLogPath = pathUtil.join(process.cwd(), 'docpad-debug.log');
|
|
|
|
DocPad.prototype.userConfigPath = '.docpad.cson';
|
|
|
|
DocPad.prototype.initialTemplateData = null;
|
|
|
|
DocPad.prototype.pluginsTemplateData = null;
|
|
|
|
DocPad.prototype.getTemplateData = function(userTemplateData) {
|
|
var docpad, locale, renderPasses, templateData, _base, _base1, _ref1;
|
|
|
|
userTemplateData || (userTemplateData = {});
|
|
docpad = this;
|
|
renderPasses = this.config.renderPasses;
|
|
locale = this.getLocale();
|
|
if ((_ref1 = this.initialTemplateData) == null) {
|
|
this.initialTemplateData = {
|
|
site: {},
|
|
getEnvironment: function() {
|
|
return docpad.getEnvironment();
|
|
},
|
|
getEnvironments: function() {
|
|
return docpad.getEnvironments();
|
|
},
|
|
referencesOthers: function(flag) {
|
|
var document;
|
|
|
|
document = this.getDocument();
|
|
document.referencesOthers();
|
|
return null;
|
|
},
|
|
getDocument: function() {
|
|
return this.documentModel;
|
|
},
|
|
getPath: function(path, parentPath) {
|
|
var document;
|
|
|
|
document = this.getDocument();
|
|
path = document.getPath(path, parentPath);
|
|
return path;
|
|
},
|
|
getFiles: function(query, sorting, paging) {
|
|
var result;
|
|
|
|
this.referencesOthers();
|
|
result = docpad.getFiles(query, sorting, paging);
|
|
return result;
|
|
},
|
|
getFile: function(query, sorting, paging) {
|
|
var result;
|
|
|
|
this.referencesOthers();
|
|
result = docpad.getFile(query, sorting, paging);
|
|
return result;
|
|
},
|
|
getFilesAtPath: function(path, sorting, paging) {
|
|
var result;
|
|
|
|
this.referencesOthers();
|
|
path = this.getPath(path);
|
|
result = docpad.getFilesAtPath(path, sorting, paging);
|
|
return result;
|
|
},
|
|
getFileAtPath: function(relativePath) {
|
|
var path, result;
|
|
|
|
this.referencesOthers();
|
|
path = this.getPath(relativePath);
|
|
result = docpad.getFileAtPath(path);
|
|
return result;
|
|
},
|
|
getDatabase: function() {
|
|
this.referencesOthers();
|
|
return docpad.getDatabase();
|
|
},
|
|
getCollection: function(name) {
|
|
this.referencesOthers();
|
|
return docpad.getCollection(name);
|
|
},
|
|
getBlock: function(name) {
|
|
return docpad.getBlock(name, true);
|
|
},
|
|
include: function(subRelativePath, strict) {
|
|
var err, file;
|
|
|
|
if (strict == null) {
|
|
strict = true;
|
|
}
|
|
file = this.getFileAtPath(subRelativePath);
|
|
if (file) {
|
|
if (strict && file.get('rendered') === false) {
|
|
if (renderPasses === 1) {
|
|
docpad.warn(util.format(locale.renderedEarlyViaInclude, subRelativePath));
|
|
}
|
|
return null;
|
|
}
|
|
return file.getOutContent();
|
|
} else {
|
|
err = new Error(util.format(locale.includeFailed, subRelativePath));
|
|
throw err;
|
|
}
|
|
}
|
|
};
|
|
}
|
|
templateData = extendr.extend({}, this.initialTemplateData, this.pluginsTemplateData, this.config.templateData, userTemplateData);
|
|
(_base = templateData.site).date || (_base.date = new Date());
|
|
(_base1 = templateData.site).keywords || (_base1.keywords = []);
|
|
if (typeChecker.isString(templateData.site.keywords)) {
|
|
templateData.site.keywords = templateData.site.keywords.split(/,\s*/g);
|
|
}
|
|
return templateData;
|
|
};
|
|
|
|
DocPad.prototype.locales = {
|
|
en: CSON.parseFileSync(pathUtil.join(__dirname, '..', '..', 'locale', 'en.cson'))
|
|
};
|
|
|
|
DocPad.prototype.locale = null;
|
|
|
|
DocPad.prototype.localeCode = null;
|
|
|
|
DocPad.prototype.getLocaleCode = function() {
|
|
var localeCode, localeCodes, _i, _len;
|
|
|
|
if ((this.localeCode != null) === false) {
|
|
localeCode = null;
|
|
localeCodes = [this.getConfig().localeCode, balUtil.getLocaleCode(), 'en_AU'];
|
|
for (_i = 0, _len = localeCodes.length; _i < _len; _i++) {
|
|
localeCode = localeCodes[_i];
|
|
if (localeCode && (this.locales[localeCode] != null)) {
|
|
break;
|
|
}
|
|
}
|
|
this.localeCode = localeCode.toLowerCase();
|
|
}
|
|
return this.localeCode;
|
|
};
|
|
|
|
DocPad.prototype.getLanguageCode = function() {
|
|
var languageCode;
|
|
|
|
if ((this.languageCode != null) === false) {
|
|
languageCode = balUtil.getLanguageCode(this.getLocaleCode());
|
|
this.languageCode = languageCode.toLowerCase();
|
|
}
|
|
return this.languageCode;
|
|
};
|
|
|
|
DocPad.prototype.getCountryCode = function() {
|
|
var countryCode;
|
|
|
|
if ((this.countryCode != null) === false) {
|
|
countryCode = balUtil.getCountryCode(this.getLocaleCode());
|
|
this.countryCode = countryCode.toLowerCase();
|
|
}
|
|
return this.countryCode;
|
|
};
|
|
|
|
DocPad.prototype.getLocale = function() {
|
|
if ((this.locale != null) === false) {
|
|
this.locale = this.locales[this.getLocaleCode()] || this.locales[this.getLanguageCode()] || this.locales['en'];
|
|
}
|
|
return this.locale;
|
|
};
|
|
|
|
DocPad.prototype.getEnvironment = function() {
|
|
var env;
|
|
|
|
env = this.getConfig().env || 'development';
|
|
return env;
|
|
};
|
|
|
|
DocPad.prototype.getEnvironments = function() {
|
|
var env, envs;
|
|
|
|
env = this.getEnvironment();
|
|
envs = env.split(/[, ]+/);
|
|
return envs;
|
|
};
|
|
|
|
DocPad.prototype.websitePackageConfig = null;
|
|
|
|
DocPad.prototype.config = null;
|
|
|
|
DocPad.prototype.instanceConfig = null;
|
|
|
|
DocPad.prototype.websiteConfig = null;
|
|
|
|
DocPad.prototype.userConfig = {
|
|
name: null,
|
|
email: null,
|
|
username: null,
|
|
subscribed: null,
|
|
subscribeTryAgain: null
|
|
};
|
|
|
|
DocPad.prototype.initialConfig = {
|
|
force: false,
|
|
enableUnlistedPlugins: true,
|
|
enabledPlugins: {},
|
|
skipUnsupportedPlugins: true,
|
|
plugins: {},
|
|
exchangeUrl: 'https://docpad.org/exchange.json',
|
|
rootPath: process.cwd(),
|
|
packagePath: 'package.json',
|
|
latestPackageUrl: 'https://docpad.org/latest.json',
|
|
configPaths: ['docpad.js', 'docpad.coffee', 'docpad.json', 'docpad.cson'],
|
|
pluginPaths: [],
|
|
pluginsPaths: ['node_modules', 'plugins'],
|
|
reloadPaths: [],
|
|
regeneratePaths: [],
|
|
regenerateDelay: 100,
|
|
outPath: 'out',
|
|
srcPath: 'src',
|
|
documentsPaths: ['documents'],
|
|
filesPaths: ['files', 'public'],
|
|
layoutsPaths: ['layouts'],
|
|
ignorePaths: false,
|
|
ignoreHiddenFiles: false,
|
|
ignoreCommonPatterns: true,
|
|
ignoreCustomPatterns: false,
|
|
watchOptions: null,
|
|
port: null,
|
|
maxAge: 86400000,
|
|
serverExpress: null,
|
|
serverHttp: null,
|
|
extendServer: true,
|
|
middlewareStandard: true,
|
|
middlewareBodyParser: true,
|
|
middlewareMethodOverride: true,
|
|
middlewareExpressRouter: true,
|
|
middleware404: true,
|
|
middleware500: true,
|
|
logLevel: ((__indexOf.call(process.argv, '-d') >= 0) ? 7 : 6),
|
|
logger: null,
|
|
growl: true,
|
|
catchExceptions: true,
|
|
reportErrors: process.argv.join('').indexOf('test') === -1,
|
|
reportStatistics: process.argv.join('').indexOf('test') === -1,
|
|
hashKey: '7>9}$3hP86o,4=@T',
|
|
airbrakeToken: 'e7374dd1c5a346efe3895b9b0c1c0325',
|
|
mixpanelToken: 'd0f9b33c0ec921350b5419352028577e',
|
|
detectEncoding: false,
|
|
renderSingleExtensions: false,
|
|
renderPasses: 1,
|
|
checkVersion: false,
|
|
welcome: false,
|
|
prompts: false,
|
|
helperUrl: 'https://docpad.org/helper/',
|
|
safeMode: false,
|
|
templateData: {},
|
|
collections: {},
|
|
events: {},
|
|
regenerateEvery: false,
|
|
localeCode: null,
|
|
env: null,
|
|
environments: {
|
|
development: {
|
|
maxAge: false,
|
|
checkVersion: process.argv.length >= 2 && /docpad$/.test(process.argv[1]),
|
|
welcome: process.argv.length >= 2 && /docpad$/.test(process.argv[1]),
|
|
prompts: process.argv.length >= 2 && /docpad$/.test(process.argv[1])
|
|
}
|
|
}
|
|
};
|
|
|
|
DocPad.prototype.regenerateTimer = null;
|
|
|
|
DocPad.prototype.getConfig = function() {
|
|
return this.config || {};
|
|
};
|
|
|
|
DocPad.prototype.getPort = function() {
|
|
var _ref1, _ref2, _ref3, _ref4;
|
|
|
|
return (_ref1 = (_ref2 = (_ref3 = (_ref4 = this.getConfig().port) != null ? _ref4 : process.env.PORT) != null ? _ref3 : process.env.VCAP_APP_PORT) != null ? _ref2 : process.env.VMC_APP_PORT) != null ? _ref1 : 9778;
|
|
};
|
|
|
|
function DocPad(instanceConfig, next) {
|
|
this.server = __bind(this.server, this);
|
|
this.serverMiddleware500 = __bind(this.serverMiddleware500, this);
|
|
this.serverMiddleware404 = __bind(this.serverMiddleware404, this);
|
|
this.serverMiddlewareRouter = __bind(this.serverMiddlewareRouter, this);
|
|
this.serveDocument = __bind(this.serveDocument, this);
|
|
this.skeleton = __bind(this.skeleton, this);
|
|
this.run = __bind(this.run, this);
|
|
this.watch = __bind(this.watch, this);
|
|
this.render = __bind(this.render, this);
|
|
this.generate = __bind(this.generate, this);
|
|
this.generatePostpare = __bind(this.generatePostpare, this);
|
|
this.generateRender = __bind(this.generateRender, this);
|
|
this.generateParse = __bind(this.generateParse, this);
|
|
this.generatePrepare = __bind(this.generatePrepare, this);
|
|
this.action = __bind(this.action, this);
|
|
this.ensureFileOrDocument = __bind(this.ensureFileOrDocument, this);
|
|
this.ensureDocument = __bind(this.ensureDocument, this);
|
|
this.ensureFile = __bind(this.ensureFile, this);
|
|
this.createDocument = __bind(this.createDocument, this);
|
|
this.createFile = __bind(this.createFile, this);
|
|
this.notify = __bind(this.notify, this);
|
|
this.warn = __bind(this.warn, this);
|
|
this.error = __bind(this.error, this);
|
|
this.log = __bind(this.log, this);
|
|
this.fatal = __bind(this.fatal, this);
|
|
this.clean = __bind(this.clean, this);
|
|
this.install = __bind(this.install, this);
|
|
this.load = __bind(this.load, this);
|
|
this.setConfig = __bind(this.setConfig, this);
|
|
this.ready = __bind(this.ready, this);
|
|
var action, configEventContext, console, docpad, logger, loggers, _ref1,
|
|
_this = this;
|
|
|
|
_ref1 = balUtil.extractOptsAndCallback(instanceConfig, next), instanceConfig = _ref1[0], next = _ref1[1];
|
|
docpad = this;
|
|
this.setMaxListeners(0);
|
|
configEventContext = {
|
|
docpad: docpad
|
|
};
|
|
this.getEvents().forEach(function(eventName) {
|
|
return docpad.on(eventName, function(opts, next) {
|
|
var args, eventHandler, _ref2;
|
|
|
|
eventHandler = (_ref2 = docpad.getConfig().events) != null ? _ref2[eventName] : void 0;
|
|
if (typeChecker.isFunction(eventHandler)) {
|
|
args = [opts, next];
|
|
return ambi.apply(null, [eventHandler.bind(configEventContext)].concat(__slice.call(args)));
|
|
} else {
|
|
return next();
|
|
}
|
|
});
|
|
});
|
|
this.actionRunnerInstance = new TaskGroup().run().on('complete', function(err) {
|
|
if (err) {
|
|
return docpad.error(err);
|
|
}
|
|
});
|
|
this.errorRunnerInstance = new TaskGroup().run().on('complete', function(err) {
|
|
var locale;
|
|
|
|
if (err && docpad.getDebugging()) {
|
|
locale = docpad.getLocale();
|
|
return docpad.log('warn', locale.reportError + '\n' + locale.errorFollows, err);
|
|
}
|
|
});
|
|
this.trackRunnerInstance = new TaskGroup().run().on('complete', function(err) {
|
|
var locale;
|
|
|
|
if (err && docpad.getDebugging()) {
|
|
locale = docpad.getLocale();
|
|
return docpad.log('warn', locale.trackError + '\n' + locale.errorFollows, err);
|
|
}
|
|
});
|
|
if ((loggers = instanceConfig.loggers)) {
|
|
delete instanceConfig.loggers;
|
|
} else {
|
|
logger = new (require('caterpillar').Logger)();
|
|
(console = logger.pipe(new (require('caterpillar-filter').Filter)).pipe(new (require('caterpillar-human').Human))).pipe(process.stdout);
|
|
loggers = {
|
|
logger: logger,
|
|
console: console
|
|
};
|
|
}
|
|
safefs.unlink(this.debugLogPath, function() {});
|
|
this.setLoggers(loggers);
|
|
this.setLogLevel(6);
|
|
this.on('log', function() {
|
|
var args;
|
|
|
|
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
|
return docpad.log.apply(this, args);
|
|
});
|
|
if (canihaz == null) {
|
|
canihaz = require('canihaz')({
|
|
installation: docpad.corePath,
|
|
location: docpad.packagePath,
|
|
key: 'lazyDependencies'
|
|
});
|
|
}
|
|
this.slowPlugins = {};
|
|
this.loadedPlugins = {};
|
|
this.exchange = {};
|
|
this.pluginsTemplateData = {};
|
|
this.instanceConfig = {};
|
|
this.collections = {};
|
|
this.blocks = {};
|
|
this.filesByUrl = {};
|
|
this.filesBySelector = {};
|
|
this.filesByOutPath = {};
|
|
this.database = new FilesCollection().on('remove', function(model, options) {
|
|
var outPath, url, _i, _len, _ref2;
|
|
|
|
if (model.get('write') === false) {
|
|
return;
|
|
}
|
|
_ref2 = model.get('urls') || [];
|
|
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
|
url = _ref2[_i];
|
|
delete docpad.filesByUrl[url];
|
|
}
|
|
outPath = model.get('outPath');
|
|
if (outPath) {
|
|
return _this.database.findAll({
|
|
outPath: outPath
|
|
}).each(function(model) {
|
|
return model.set({
|
|
'mtime': new Date()
|
|
});
|
|
});
|
|
}
|
|
}).on('change:urls', function(model, urls, options) {
|
|
var url, _i, _j, _len, _len1, _ref2, _results;
|
|
|
|
if (urls == null) {
|
|
urls = [];
|
|
}
|
|
if (model.get('write') === false) {
|
|
return;
|
|
}
|
|
_ref2 = model.previous('urls') || [];
|
|
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
|
url = _ref2[_i];
|
|
delete docpad.filesByUrl[url];
|
|
}
|
|
_results = [];
|
|
for (_j = 0, _len1 = urls.length; _j < _len1; _j++) {
|
|
url = urls[_j];
|
|
_results.push(docpad.filesByUrl[url] = model.cid);
|
|
}
|
|
return _results;
|
|
}).on('change:outPath', function(model, outPath, options) {
|
|
var existingModel, existingModelId, existingModelPath, message, modelPath, previousModelId, previousModels, previousOutPath, _base, _ref2;
|
|
|
|
if (model.get('write') === false) {
|
|
return;
|
|
}
|
|
previousOutPath = model.previous('outPath');
|
|
if (previousOutPath) {
|
|
previousModels = _this.database.findAll({
|
|
outPath: previousOutPath
|
|
});
|
|
previousModels.each(function(model) {
|
|
return model.set({
|
|
'mtime': new Date()
|
|
});
|
|
});
|
|
previousModelId = _this.filesByOutPath[previousOutPath];
|
|
if (previousModelId === model.id) {
|
|
if (previousModels.length) {
|
|
_this.filesByOutPath[previousOutPath] = previousModelId;
|
|
} else {
|
|
delete _this.filesByOutPath[previousOutPath];
|
|
}
|
|
}
|
|
}
|
|
existingModelId = (_ref2 = (_base = _this.filesByOutPath)[outPath]) != null ? _ref2 : _base[outPath] = model.id;
|
|
if (existingModelId !== model.id) {
|
|
modelPath = model.get('fullPath');
|
|
existingModel = _this.database.get(existingModelId);
|
|
existingModelPath = existingModel.get('fullPath');
|
|
message = util.format(docpad.getLocale().outPathConflict, outPath, modelPath, existingModelPath);
|
|
return docpad.warn(message);
|
|
}
|
|
});
|
|
this.locales = extendr.dereference(this.locales);
|
|
this.userConfig = extendr.dereference(this.userConfig);
|
|
this.initialConfig = extendr.dereference(this.initialConfig);
|
|
if (instanceConfig.action != null) {
|
|
action = instanceConfig.action;
|
|
} else {
|
|
action = 'load ready';
|
|
}
|
|
if (action) {
|
|
this.action(action, instanceConfig, function(err) {
|
|
if (err) {
|
|
return docpad.fatal(err);
|
|
}
|
|
return typeof next === "function" ? next(null, docpad) : void 0;
|
|
});
|
|
} else {
|
|
if (typeof next === "function") {
|
|
next(null, docpad);
|
|
}
|
|
}
|
|
this;
|
|
}
|
|
|
|
DocPad.prototype.isIgnoredPath = function(path, opts) {
|
|
if (opts == null) {
|
|
opts = {};
|
|
}
|
|
opts = extendr.extend({
|
|
ignorePaths: this.config.ignorePaths,
|
|
ignoreHiddenFiles: this.config.ignoreHiddenFiles,
|
|
ignoreCommonPatterns: this.config.ignoreCommonPatterns,
|
|
ignoreCustomPatterns: this.config.ignoreCustomPatterns
|
|
}, opts);
|
|
return balUtil.isIgnoredPath(path, opts);
|
|
};
|
|
|
|
DocPad.prototype.scandir = function(opts) {
|
|
if (opts == null) {
|
|
opts = {};
|
|
}
|
|
opts = extendr.extend({
|
|
ignorePaths: this.config.ignorePaths,
|
|
ignoreHiddenFiles: this.config.ignoreHiddenFiles,
|
|
ignoreCommonPatterns: this.config.ignoreCommonPatterns,
|
|
ignoreCustomPatterns: this.config.ignoreCustomPatterns
|
|
}, opts);
|
|
return balUtil.scandir(opts);
|
|
};
|
|
|
|
DocPad.prototype.watchdir = function(opts) {
|
|
if (opts == null) {
|
|
opts = {};
|
|
}
|
|
opts = extendr.extend({
|
|
ignorePaths: this.config.ignorePaths,
|
|
ignoreHiddenFiles: this.config.ignoreHiddenFiles,
|
|
ignoreCommonPatterns: this.config.ignoreCommonPatterns,
|
|
ignoreCustomPatterns: this.config.ignoreCustomPatterns
|
|
}, opts, this.config.watchOptions);
|
|
return require('watchr').watch(opts);
|
|
};
|
|
|
|
DocPad.prototype.ready = function(opts, next) {
|
|
var config, docpad, instanceConfig, locale, mixpanelInstance, pluginName, pluginsList, tasks, _ref1,
|
|
_this = this;
|
|
|
|
_ref1 = balUtil.extractOptsAndCallback(instanceConfig, next), instanceConfig = _ref1[0], next = _ref1[1];
|
|
docpad = this;
|
|
config = this.getConfig();
|
|
locale = this.getLocale();
|
|
mixpanelInstance = this.getMixpanelInstance();
|
|
this.DocumentModel.prototype.defaults.renderSingleExtensions = config.renderSingleExtensions;
|
|
this.compareVersion();
|
|
if (this.getDebugging()) {
|
|
pluginsList = ((function() {
|
|
var _i, _len, _ref2, _results;
|
|
|
|
_ref2 = Object.keys(this.loadedPlugins).sort();
|
|
_results = [];
|
|
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
|
pluginName = _ref2[_i];
|
|
_results.push("" + pluginName + " v" + this.loadedPlugins[pluginName].version);
|
|
}
|
|
return _results;
|
|
}).call(this)).join(', ');
|
|
} else {
|
|
pluginsList = Object.keys(this.loadedPlugins).sort().join(', ');
|
|
}
|
|
this.log('info', util.format(locale.welcome, "v" + (this.getVersion())));
|
|
this.log('info', util.format(locale.welcomePlugins, pluginsList));
|
|
this.log('info', util.format(locale.welcomeEnvironment, this.getEnvironment()));
|
|
tasks = new TaskGroup().once('complete', function(err) {
|
|
if (err) {
|
|
return docpad.error(err);
|
|
}
|
|
return typeof next === "function" ? next(null, docpad) : void 0;
|
|
});
|
|
tasks.addTask(function(complete) {
|
|
if (!config.welcome) {
|
|
return complete();
|
|
}
|
|
return _this.emitSync('welcome', {
|
|
docpad: docpad
|
|
}, complete);
|
|
});
|
|
tasks.addTask(function(complete) {
|
|
if (!mixpanelInstance || _this.userConfig.username) {
|
|
return complete();
|
|
}
|
|
return require('getmac').getMac(function(err, macAddress) {
|
|
var macAddressHash, _base, _base1, _ref2, _ref3;
|
|
|
|
if (err || !macAddress) {
|
|
return complete();
|
|
}
|
|
try {
|
|
macAddressHash = require('crypto').createHmac('sha1', config.hashKey).update(macAddress).digest('hex');
|
|
} catch (_error) {
|
|
err = _error;
|
|
if (err) {
|
|
return complete();
|
|
}
|
|
}
|
|
if (macAddressHash) {
|
|
if ((_ref2 = (_base = _this.userConfig).name) == null) {
|
|
_base.name = "MAC " + macAddressHash;
|
|
}
|
|
if ((_ref3 = (_base1 = _this.userConfig).username) == null) {
|
|
_base1.username = macAddressHash;
|
|
}
|
|
}
|
|
return complete();
|
|
});
|
|
});
|
|
tasks.addTask(function() {
|
|
var lastLogin, userData;
|
|
|
|
if (!mixpanelInstance || !_this.userConfig.username) {
|
|
return;
|
|
}
|
|
lastLogin = new Date();
|
|
userData = {
|
|
$email: _this.userConfig.email,
|
|
$name: _this.userConfig.name,
|
|
$last_login: lastLogin,
|
|
$country_code: balUtil.getCountryCode(),
|
|
languageCode: balUtil.getLanguageCode(),
|
|
version: _this.getVersion(),
|
|
platform: _this.getProcessPlatform(),
|
|
nodeVersion: _this.getProcessVersion()
|
|
};
|
|
if (_this.userConfig.identified !== true) {
|
|
mixpanelInstance.people.set(_this.userConfig.username, extendr.extend(userData, {
|
|
$created: lastLogin,
|
|
$username: _this.userConfig.username
|
|
}));
|
|
return _this.updateUserConfig({
|
|
identified: true
|
|
});
|
|
} else {
|
|
return mixpanelInstance.people.set(_this.userConfig.username, userData);
|
|
}
|
|
});
|
|
tasks.addTask(function(complete) {
|
|
return _this.emitSync('docpadReady', {
|
|
docpad: docpad
|
|
}, complete);
|
|
});
|
|
tasks.run();
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.mergeConfigurations = function(configPackages, configsToMerge) {
|
|
var configPackage, env, envConfig, envs, _i, _j, _len, _len1, _ref1;
|
|
|
|
envs = this.getEnvironments();
|
|
for (_i = 0, _len = configPackages.length; _i < _len; _i++) {
|
|
configPackage = configPackages[_i];
|
|
if (!configPackage) {
|
|
continue;
|
|
}
|
|
configsToMerge.push(configPackage);
|
|
for (_j = 0, _len1 = envs.length; _j < _len1; _j++) {
|
|
env = envs[_j];
|
|
envConfig = (_ref1 = configPackage.environments) != null ? _ref1[env] : void 0;
|
|
if (envConfig) {
|
|
configsToMerge.push(envConfig);
|
|
}
|
|
}
|
|
}
|
|
extendr.safeDeepExtendPlainObjects.apply(extendr, configsToMerge);
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.setInstanceConfig = function(instanceConfig) {
|
|
if (instanceConfig) {
|
|
extendr.safeDeepExtendPlainObjects(this.instanceConfig, instanceConfig);
|
|
if (this.config) {
|
|
extendr.safeDeepExtendPlainObjects(this.config, instanceConfig);
|
|
}
|
|
}
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.setConfig = function(instanceConfig, next) {
|
|
var configPackages, configsToMerge, docpad, key, postTasks, type, typePath, typePaths, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref1, _ref2, _ref3,
|
|
_this = this;
|
|
|
|
_ref1 = balUtil.extractOptsAndCallback(instanceConfig, next), instanceConfig = _ref1[0], next = _ref1[1];
|
|
docpad = this;
|
|
if (instanceConfig) {
|
|
this.setInstanceConfig(instanceConfig);
|
|
}
|
|
this.config.env = this.instanceConfig.env || this.websiteConfig.env || this.initialConfig.env || process.env.NODE_ENV;
|
|
configPackages = [this.initialConfig, this.userConfig, this.websiteConfig, this.instanceConfig];
|
|
configsToMerge = [this.config];
|
|
docpad.mergeConfigurations(configPackages, configsToMerge);
|
|
if (this.config.server) {
|
|
this.setServer(this.config.server);
|
|
}
|
|
this.setLogLevel(this.config.logLevel);
|
|
this.config.rootPath = pathUtil.resolve(this.config.rootPath);
|
|
this.config.outPath = pathUtil.resolve(this.config.rootPath, this.config.outPath);
|
|
this.config.srcPath = pathUtil.resolve(this.config.rootPath, this.config.srcPath);
|
|
_ref2 = ['documents', 'files', 'layouts'];
|
|
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
|
type = _ref2[_i];
|
|
typePaths = this.config[type + 'Paths'];
|
|
for (key = _j = 0, _len1 = typePaths.length; _j < _len1; key = ++_j) {
|
|
typePath = typePaths[key];
|
|
typePaths[key] = pathUtil.resolve(this.config.srcPath, typePath);
|
|
}
|
|
}
|
|
_ref3 = ['plugins'];
|
|
for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) {
|
|
type = _ref3[_k];
|
|
typePaths = this.config[type + 'Paths'];
|
|
for (key = _l = 0, _len3 = typePaths.length; _l < _len3; key = ++_l) {
|
|
typePath = typePaths[key];
|
|
typePaths[key] = pathUtil.resolve(this.config.rootPath, typePath);
|
|
}
|
|
}
|
|
process.removeListener('uncaughtException', this.error);
|
|
if (this.config.catchExceptions) {
|
|
process.setMaxListeners(0);
|
|
process.on('uncaughtException', this.error);
|
|
}
|
|
if (this.regenerateTimer) {
|
|
clearInterval(this.regenerateTimer);
|
|
this.regenerateTimer = null;
|
|
}
|
|
if (this.config.regenerateEvery) {
|
|
this.regenerateTimer = setInterval(function() {
|
|
docpad.log('info', locale.renderInterval);
|
|
return docpad.action('generate');
|
|
}, this.config.regenerateEvery);
|
|
}
|
|
postTasks = new TaskGroup().once('complete', function(err) {
|
|
return next(err, _this.config);
|
|
});
|
|
postTasks.addTask(function(complete) {
|
|
if (!_this.config.detectEncoding) {
|
|
return complete();
|
|
}
|
|
return canihaz('iconv', complete);
|
|
});
|
|
postTasks.addTask(function(complete) {
|
|
return _this.loadPlugins(complete);
|
|
});
|
|
postTasks.addTask(function(complete) {
|
|
return _this.extendCollections(complete);
|
|
});
|
|
postTasks.addTask(function(complete) {
|
|
return _this.emitSync('extendTemplateData', {
|
|
templateData: _this.pluginsTemplateData
|
|
}, complete);
|
|
});
|
|
postTasks.addTask(function(complete) {
|
|
return _this.emitSync('docpadLoaded', {}, complete);
|
|
});
|
|
postTasks.run();
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.load = function(instanceConfig, next) {
|
|
var docpad, locale, preTasks, _ref1,
|
|
_this = this;
|
|
|
|
_ref1 = balUtil.extractOptsAndCallback(instanceConfig, next), instanceConfig = _ref1[0], next = _ref1[1];
|
|
docpad = this;
|
|
locale = this.getLocale();
|
|
instanceConfig || (instanceConfig = {});
|
|
this.websitePackageConfig = {};
|
|
this.websiteConfig = {};
|
|
this.config = {};
|
|
this.setInstanceConfig(instanceConfig);
|
|
preTasks = new TaskGroup().once('complete', function(err) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
return _this.setConfig(next);
|
|
});
|
|
preTasks.addTask(function(complete) {
|
|
return balUtil.getHomePath(function(err, homePath) {
|
|
var dropboxPath;
|
|
|
|
if (err) {
|
|
return complete(err);
|
|
}
|
|
dropboxPath = pathUtil.join(homePath, 'Dropbox');
|
|
return safefs.exists(dropboxPath, function(dropboxPathExists) {
|
|
var userConfigDirPath;
|
|
|
|
userConfigDirPath = dropboxPathExists ? dropboxPath : homePath;
|
|
_this.userConfigPath = pathUtil.join(userConfigDirPath, _this.userConfigPath);
|
|
return complete();
|
|
});
|
|
});
|
|
});
|
|
preTasks.addTask(function(complete) {
|
|
return _this.loadConfigPath(_this.userConfigPath, function(err, data) {
|
|
if (err) {
|
|
return complete(err);
|
|
}
|
|
extendr.extend(_this.userConfig, data || {});
|
|
return complete();
|
|
});
|
|
});
|
|
preTasks.addTask(function(complete) {
|
|
return _this.loadConfigPath(_this.packagePath, function(err, data) {
|
|
var _ref2;
|
|
|
|
if (err) {
|
|
return complete(err);
|
|
}
|
|
data || (data = {});
|
|
_this.version = data.version;
|
|
if ((_ref2 = _this.getAirbrakeInstance()) != null) {
|
|
_ref2.appVersion = data.version;
|
|
}
|
|
return complete();
|
|
});
|
|
});
|
|
preTasks.addTask(function(complete) {
|
|
var rootPath, websitePackagePath;
|
|
|
|
rootPath = pathUtil.resolve(_this.instanceConfig.rootPath || _this.initialConfig.rootPath);
|
|
websitePackagePath = pathUtil.resolve(rootPath, _this.instanceConfig.packagePath || _this.initialConfig.packagePath);
|
|
return _this.loadConfigPath(websitePackagePath, function(err, data) {
|
|
if (err) {
|
|
return complete(err);
|
|
}
|
|
data || (data = {});
|
|
_this.websitePackageConfig = data;
|
|
return complete();
|
|
});
|
|
});
|
|
preTasks.addTask(function(complete) {
|
|
var envPath, rootPath;
|
|
|
|
rootPath = pathUtil.resolve(_this.instanceConfig.rootPath || _this.websitePackageConfig.rootPath || _this.initialConfig.rootPath);
|
|
envPath = pathUtil.join(rootPath, '.env');
|
|
return safefs.exists(envPath, function(exists) {
|
|
if (!exists) {
|
|
return complete();
|
|
}
|
|
return safefs.readFile(envPath, function(err, data) {
|
|
var key, line, lines, match, result, value, _i, _len;
|
|
|
|
if (err) {
|
|
return complete(err);
|
|
}
|
|
result = data.toString();
|
|
lines = result.split('\n');
|
|
for (_i = 0, _len = lines.length; _i < _len; _i++) {
|
|
line = lines[_i];
|
|
match = line.match(/^([^=]+?)=(.*)/);
|
|
if (match) {
|
|
key = match[1];
|
|
value = match[2];
|
|
process.env[key] = value;
|
|
}
|
|
}
|
|
return complete();
|
|
});
|
|
});
|
|
});
|
|
preTasks.addTask(function(complete) {
|
|
var configPath, configPaths, index, rootPath, _i, _len;
|
|
|
|
rootPath = pathUtil.resolve(_this.instanceConfig.rootPath || _this.initialConfig.rootPath);
|
|
configPaths = _this.instanceConfig.configPaths || _this.initialConfig.configPaths;
|
|
for (index = _i = 0, _len = configPaths.length; _i < _len; index = ++_i) {
|
|
configPath = configPaths[index];
|
|
configPaths[index] = pathUtil.resolve(rootPath, configPath);
|
|
}
|
|
return _this.loadConfigPaths(configPaths, function(err, data) {
|
|
if (err) {
|
|
return complete(err);
|
|
}
|
|
data || (data = {});
|
|
extendr.extend(_this.websiteConfig, data);
|
|
return complete();
|
|
});
|
|
});
|
|
preTasks.run();
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.install = function(opts, next) {
|
|
var docpad, _ref1;
|
|
|
|
_ref1 = balUtil.extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
|
|
docpad = this;
|
|
this.initNodeModules({
|
|
path: this.config.rootPath,
|
|
output: true,
|
|
next: function(err) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
return docpad.load(function(err) {
|
|
return next(err);
|
|
});
|
|
}
|
|
});
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.clean = function(opts, next) {
|
|
var docpad, locale, outPath, rootPath, _ref1, _ref2;
|
|
|
|
_ref1 = balUtil.extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
|
|
docpad = this;
|
|
locale = this.getLocale();
|
|
_ref2 = this.config, rootPath = _ref2.rootPath, outPath = _ref2.outPath;
|
|
docpad.log('debug', locale.renderCleaning);
|
|
docpad.resetCollections(function(err) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
if (rootPath.indexOf(outPath) !== -1) {
|
|
return next();
|
|
} else {
|
|
return balUtil.rmdirDeep(outPath, function(err, list, tree) {
|
|
if (!err) {
|
|
docpad.log('debug', locale.renderCleaned);
|
|
}
|
|
return next();
|
|
});
|
|
}
|
|
});
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.updateUserConfig = function(data, next) {
|
|
var docpad, userConfigPath, _ref1;
|
|
|
|
if (data == null) {
|
|
data = {};
|
|
}
|
|
_ref1 = balUtil.extractOptsAndCallback(data, next), data = _ref1[0], next = _ref1[1];
|
|
docpad = this;
|
|
userConfigPath = this.userConfigPath;
|
|
if (data) {
|
|
extendr.extend(this.userConfig, data);
|
|
}
|
|
CSON.stringify(this.userConfig, function(err, userConfigString) {
|
|
if (err) {
|
|
return typeof next === "function" ? next(err) : void 0;
|
|
}
|
|
return safefs.writeFile(userConfigPath, userConfigString, 'utf8', function(err) {
|
|
return typeof next === "function" ? next(err) : void 0;
|
|
});
|
|
});
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.loadConfigUrl = function(configUrl, next) {
|
|
var locale;
|
|
|
|
locale = this.getLocale();
|
|
this.log('debug', util.format(locale.loadingConfigUrl, configUrl));
|
|
balUtil.readPath(configUrl, function(err, body) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
return CSON.parse(body, next);
|
|
});
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.loadConfigPath = function(configPath, next) {
|
|
var locale;
|
|
|
|
locale = this.getLocale();
|
|
this.log('debug', util.format(locale.loadingConfigPath, configPath));
|
|
safefs.exists(configPath, function(exists) {
|
|
if (!exists) {
|
|
return next(null, null);
|
|
}
|
|
return CSON.parseFile(configPath, next);
|
|
});
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.loadConfigPaths = function(configPaths, next) {
|
|
var docpad, result, tasks;
|
|
|
|
docpad = this;
|
|
result = null;
|
|
if (!typeChecker.isArray(configPaths)) {
|
|
configPaths = [configPaths];
|
|
}
|
|
tasks = new TaskGroup().once('complete', function(err) {
|
|
return next(err, result);
|
|
});
|
|
configPaths.forEach(function(configPath) {
|
|
return tasks.addTask(function(complete) {
|
|
if (result) {
|
|
return complete();
|
|
}
|
|
return docpad.loadConfigPath(configPath, function(err, config) {
|
|
if (err) {
|
|
return complete(err);
|
|
}
|
|
if (config) {
|
|
result = config;
|
|
tasks.clear();
|
|
return complete();
|
|
} else {
|
|
return complete();
|
|
}
|
|
});
|
|
});
|
|
});
|
|
tasks.run();
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.extendCollections = function(next) {
|
|
var config, database, docpad, locale, tasks;
|
|
|
|
docpad = this;
|
|
config = this.config;
|
|
locale = this.getLocale();
|
|
database = this.getDatabase();
|
|
this.setCollections({
|
|
documents: database.createLiveChildCollection().setQuery('isDocument', {
|
|
$or: {
|
|
isDocument: true,
|
|
fullPath: {
|
|
$startsWith: config.documentsPaths
|
|
}
|
|
}
|
|
}).on('add', function(model) {
|
|
docpad.log('debug', util.format(locale.addingDocument, model.attributes.fullPath));
|
|
return model.setDefaults({
|
|
isDocument: true,
|
|
render: true,
|
|
write: true
|
|
});
|
|
}),
|
|
files: database.createLiveChildCollection().setQuery('isFile', {
|
|
$or: {
|
|
isFile: true,
|
|
fullPath: {
|
|
$startsWith: config.filesPaths
|
|
}
|
|
}
|
|
}).on('add', function(model) {
|
|
docpad.log('debug', util.format(locale.addingFile, model.attributes.fullPath));
|
|
return model.setDefaults({
|
|
isFile: true,
|
|
render: false,
|
|
write: true
|
|
});
|
|
}),
|
|
layouts: database.createLiveChildCollection().setQuery('isLayout', {
|
|
$or: {
|
|
isLayout: true,
|
|
fullPath: {
|
|
$startsWith: config.layoutsPaths
|
|
}
|
|
}
|
|
}).on('add', function(model) {
|
|
docpad.log('debug', util.format(locale.addingLayout, model.attributes.fullPath));
|
|
return model.setDefaults({
|
|
isLayout: true,
|
|
render: false,
|
|
write: false
|
|
});
|
|
}),
|
|
html: database.createLiveChildCollection().setQuery('isHTML', {
|
|
$or: {
|
|
isDocument: true,
|
|
isFile: true
|
|
},
|
|
outExtension: 'html'
|
|
}).on('add', function(model) {
|
|
return docpad.log('debug', util.format(locale.addingHtml, model.attributes.fullPath));
|
|
}),
|
|
stylesheet: database.createLiveChildCollection().setQuery('isStylesheet', {
|
|
$or: {
|
|
isDocument: true,
|
|
isFile: true
|
|
},
|
|
outExtension: {
|
|
$in: ['css', 'scss', 'sass', 'styl', 'stylus', 'less']
|
|
}
|
|
}).on('add', function(model) {
|
|
docpad.log('debug', util.format(locale.addingStylesheet, model.attributes.fullPath));
|
|
return model.setDefaults({
|
|
referencesOthers: true
|
|
});
|
|
})
|
|
});
|
|
this.setBlocks({
|
|
meta: new MetaCollection(),
|
|
scripts: new ScriptsCollection(),
|
|
styles: new StylesCollection()
|
|
});
|
|
tasks = new TaskGroup().setConfig({
|
|
concurrency: 0
|
|
}).once('complete', function(err) {
|
|
if (err) {
|
|
docpad.error(err);
|
|
}
|
|
return docpad.emitSync('extendCollections', {}, next);
|
|
});
|
|
eachr(this.config.collections || {}, function(fn, name) {
|
|
return tasks.addTask(function(complete) {
|
|
var collection;
|
|
|
|
if (fn.length === 2) {
|
|
return fn.call(docpad, database, function(err, collection) {
|
|
if (err) {
|
|
docpad.error(err);
|
|
}
|
|
if (collection) {
|
|
collection.live(true);
|
|
}
|
|
docpad.setCollection(name, collection);
|
|
return complete();
|
|
});
|
|
} else {
|
|
collection = fn.call(docpad, database);
|
|
if (collection) {
|
|
collection.live(true);
|
|
}
|
|
docpad.setCollection(name, collection);
|
|
return complete();
|
|
}
|
|
});
|
|
});
|
|
tasks.run();
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.resetCollections = function(next) {
|
|
var database;
|
|
|
|
database = this.getDatabase();
|
|
this.databaseCache = new FilesCollection(database.models);
|
|
database.reset([]);
|
|
this.getBlock('meta').reset([]).add(["<meta http-equiv=\"X-Powered-By\" content=\"DocPad v" + docpad.version + "\"/>"]);
|
|
this.getBlock('scripts').reset([]);
|
|
this.getBlock('styles').reset([]);
|
|
this.filesByUrl = {};
|
|
this.filesBySelector = {};
|
|
this.filesByOutPath = {};
|
|
this.emitSync('populateCollections', {}, next);
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.initGitRepo = function(opts) {
|
|
balUtil.initGitRepo(opts);
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.initNodeModules = function(opts) {
|
|
var _ref1, _ref2;
|
|
|
|
if (opts == null) {
|
|
opts = {};
|
|
}
|
|
if ((_ref1 = opts.force) == null) {
|
|
opts.force = this.config.force;
|
|
}
|
|
if ((_ref2 = opts.output) == null) {
|
|
opts.output = this.getDebugging();
|
|
}
|
|
balUtil.initNodeModules(opts);
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.setLogLevel = function(level) {
|
|
var loggers, _ref1;
|
|
|
|
this.getLogger().setConfig({
|
|
level: level
|
|
});
|
|
if (level === 7) {
|
|
loggers = this.getLoggers();
|
|
if ((_ref1 = loggers.debug) == null) {
|
|
loggers.debug = loggers.logger.pipe(new (require('caterpillar-human').Human)({
|
|
color: false
|
|
})).pipe(require('fs').createWriteStream(this.debugLogPath));
|
|
}
|
|
}
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.getLogLevel = function() {
|
|
return this.config.logLevel;
|
|
};
|
|
|
|
DocPad.prototype.getDebugging = function() {
|
|
return this.getLogLevel() === 7;
|
|
};
|
|
|
|
DocPad.prototype.fatal = function(err) {
|
|
var config, docpad;
|
|
|
|
docpad = this;
|
|
config = this.getConfig();
|
|
if (!err) {
|
|
return this;
|
|
}
|
|
this.error(err, 'err', function() {
|
|
if (config.catchExceptions) {
|
|
return process.exit(-1);
|
|
} else {
|
|
throw err;
|
|
}
|
|
});
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.log = function() {
|
|
var args, logger;
|
|
|
|
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
|
logger = this.getLogger();
|
|
logger.log.apply(logger, args);
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.error = function(err, type, next) {
|
|
var airbrake, docpad, locale, _ref1;
|
|
|
|
if (type == null) {
|
|
type = 'err';
|
|
}
|
|
docpad = this;
|
|
locale = this.getLocale();
|
|
if (!err || err.logged) {
|
|
if (typeof next === "function") {
|
|
next();
|
|
}
|
|
return this;
|
|
}
|
|
err.logged = true;
|
|
if (err.message == null) {
|
|
err = new Error(err);
|
|
}
|
|
err.logged = true;
|
|
docpad.log(type, locale.errorOccured, '\n' + ((_ref1 = err.stack) != null ? _ref1 : err.message));
|
|
docpad.notify(err.message, {
|
|
title: locale.errorOccured
|
|
});
|
|
airbrake = this.getAirbrakeInstance();
|
|
if (airbrake) {
|
|
err.params = {
|
|
docpadVersion: this.version,
|
|
docpadConfig: this.config
|
|
};
|
|
this.getErrorRunner().addTask(function(complete) {
|
|
return airbrake.notify(err, function(airbrakeErr, airbrakeUrl) {
|
|
if (airbrakeErr) {
|
|
return complete(airbrakeErr);
|
|
} else {
|
|
console.log(util.format(locale.errorLoggedTo, airbrakeUrl));
|
|
return complete();
|
|
}
|
|
});
|
|
});
|
|
} else {
|
|
if (typeof next === "function") {
|
|
next();
|
|
}
|
|
}
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.warn = function(message, err, next) {
|
|
var docpad, locale;
|
|
|
|
docpad = this;
|
|
locale = this.getLocale();
|
|
docpad.log('warn', message);
|
|
if (err) {
|
|
docpad.error(err, 'warn', next);
|
|
}
|
|
docpad.notify(message, {
|
|
title: locale.warnOccured
|
|
});
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.notify = function(message, opts) {
|
|
var docpad, err, growl;
|
|
|
|
docpad = this;
|
|
growl = this.getGrowlInstance();
|
|
if (growl) {
|
|
try {
|
|
growl(message, opts);
|
|
} catch (_error) {
|
|
err = _error;
|
|
}
|
|
}
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.track = function(name, data, next) {
|
|
var mixpanelInstance, _ref1, _ref2;
|
|
|
|
if (data == null) {
|
|
data = {};
|
|
}
|
|
mixpanelInstance = this.getMixpanelInstance();
|
|
if (mixpanelInstance) {
|
|
if ((_ref1 = this.userConfig) != null ? _ref1.username : void 0) {
|
|
data.distinct_id = this.userConfig.username;
|
|
data.username = this.userConfig.username;
|
|
}
|
|
if ((_ref2 = this.websitePackageConfig) != null ? _ref2.name : void 0) {
|
|
data.websiteName = this.websitePackageConfig.name;
|
|
}
|
|
data.version = this.getVersion();
|
|
data.platform = this.getProcessPlatform();
|
|
data.nodeVersion = this.getProcessVersion();
|
|
data.environment = this.getEnvironment();
|
|
eachr(this.loadedPlugins, function(value, key) {
|
|
return data['plugin-' + key] = value.version || true;
|
|
});
|
|
this.getTrackRunner().addTask(function(complete) {
|
|
return mixpanelInstance.track(name, data, function(err) {
|
|
if (typeof next === "function") {
|
|
next();
|
|
}
|
|
return complete(err);
|
|
});
|
|
});
|
|
}
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.createFile = function(data, options) {
|
|
var docpad, file;
|
|
|
|
if (data == null) {
|
|
data = {};
|
|
}
|
|
if (options == null) {
|
|
options = {};
|
|
}
|
|
docpad = this;
|
|
options = extendr.extend({
|
|
detectEncoding: this.config.detectEncoding,
|
|
outDirPath: this.config.outPath
|
|
}, options);
|
|
file = new FileModel(data, options);
|
|
file.on('log', function() {
|
|
var args;
|
|
|
|
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
|
return docpad.log.apply(docpad, args);
|
|
});
|
|
file.on('render', function() {
|
|
var args;
|
|
|
|
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
|
return docpad.emitSync.apply(docpad, ['render'].concat(__slice.call(args)));
|
|
});
|
|
return file;
|
|
};
|
|
|
|
DocPad.prototype.createDocument = function(data, options) {
|
|
var docpad, document;
|
|
|
|
if (data == null) {
|
|
data = {};
|
|
}
|
|
if (options == null) {
|
|
options = {};
|
|
}
|
|
docpad = this;
|
|
options = extendr.extend({
|
|
detectEncoding: this.config.detectEncoding,
|
|
outDirPath: this.config.outPath
|
|
}, options);
|
|
document = new DocumentModel(data, options);
|
|
document.on('log', function() {
|
|
var args;
|
|
|
|
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
|
return docpad.log.apply(docpad, args);
|
|
});
|
|
document.on('getLayout', function(opts, next) {
|
|
var layout;
|
|
|
|
if (opts == null) {
|
|
opts = {};
|
|
}
|
|
opts.collection = docpad.getCollection('layouts');
|
|
layout = docpad.getFileBySelector(opts.selector, opts);
|
|
return next(null, {
|
|
layout: layout
|
|
});
|
|
});
|
|
document.on('render', function() {
|
|
var args;
|
|
|
|
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
|
return docpad.emitSync.apply(docpad, ['render'].concat(__slice.call(args)));
|
|
});
|
|
document.on('renderDocument', function() {
|
|
var args;
|
|
|
|
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
|
return docpad.emitSync.apply(docpad, ['renderDocument'].concat(__slice.call(args)));
|
|
});
|
|
return document;
|
|
};
|
|
|
|
DocPad.prototype.ensureFile = function(data, options) {
|
|
var database, result;
|
|
|
|
if (data == null) {
|
|
data = {};
|
|
}
|
|
if (options == null) {
|
|
options = {};
|
|
}
|
|
database = this.getDatabase();
|
|
result = database.findOne({
|
|
fullPath: data.fullPath
|
|
});
|
|
if (!result) {
|
|
result = this.createFile(data, options);
|
|
database.add(result);
|
|
}
|
|
return result;
|
|
};
|
|
|
|
DocPad.prototype.ensureDocument = function(data, options) {
|
|
var database, result;
|
|
|
|
if (data == null) {
|
|
data = {};
|
|
}
|
|
if (options == null) {
|
|
options = {};
|
|
}
|
|
database = this.getDatabase();
|
|
result = database.findOne({
|
|
fullPath: data.fullPath
|
|
});
|
|
if (!result) {
|
|
result = this.createDocument(data, options);
|
|
database.add(result);
|
|
}
|
|
return result;
|
|
};
|
|
|
|
DocPad.prototype.ensureFileOrDocument = function(data, options) {
|
|
var config, database, dirPath, docpad, fileFullPath, result, _i, _j, _len, _len1, _ref1, _ref2;
|
|
|
|
if (data == null) {
|
|
data = {};
|
|
}
|
|
if (options == null) {
|
|
options = {};
|
|
}
|
|
docpad = this;
|
|
config = this.getConfig();
|
|
database = this.getDatabase();
|
|
fileFullPath = data.fullPath || null;
|
|
result = database.findOne({
|
|
fullPath: fileFullPath
|
|
});
|
|
if (!result) {
|
|
if (fileFullPath) {
|
|
_ref1 = config.documentsPaths.concat(config.layoutsPaths);
|
|
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
|
|
dirPath = _ref1[_i];
|
|
if (fileFullPath.indexOf(dirPath) === 0) {
|
|
data.relativePath || (data.relativePath = fileFullPath.replace(dirPath, '').replace(/^[\/\\]/, ''));
|
|
result = this.createDocument(data, options);
|
|
break;
|
|
}
|
|
}
|
|
if (!result) {
|
|
_ref2 = config.filesPaths;
|
|
for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
|
|
dirPath = _ref2[_j];
|
|
if (fileFullPath.indexOf(dirPath) === 0) {
|
|
data.relativePath || (data.relativePath = fileFullPath.replace(dirPath, '').replace(/^[\/\\]/, ''));
|
|
result = this.createFile(data, options);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!result) {
|
|
result = this.createDocument(data, options);
|
|
}
|
|
database.add(result);
|
|
}
|
|
return result;
|
|
};
|
|
|
|
DocPad.prototype.parseFileDirectory = function(opts, next) {
|
|
var _ref1;
|
|
|
|
if (opts == null) {
|
|
opts = {};
|
|
}
|
|
if ((_ref1 = opts.createFunction) == null) {
|
|
opts.createFunction = this.createFile;
|
|
}
|
|
return this.parseDirectory(opts, next);
|
|
};
|
|
|
|
DocPad.prototype.parseDocumentDirectory = function(opts, next) {
|
|
var _ref1;
|
|
|
|
if (opts == null) {
|
|
opts = {};
|
|
}
|
|
if ((_ref1 = opts.createFunction) == null) {
|
|
opts.createFunction = this.createDocument;
|
|
}
|
|
return this.parseDirectory(opts, next);
|
|
};
|
|
|
|
DocPad.prototype.parseDirectory = function(opts, next) {
|
|
var createFunction, docpad, filesToLoad, locale, path;
|
|
|
|
if (opts == null) {
|
|
opts = {};
|
|
}
|
|
docpad = this;
|
|
locale = this.getLocale();
|
|
path = opts.path, createFunction = opts.createFunction;
|
|
filesToLoad = new FilesCollection();
|
|
if (!safefs.existsSync(path)) {
|
|
docpad.log('debug', util.format(locale.renderDirectoryNonexistant, path));
|
|
return next();
|
|
}
|
|
docpad.log('debug', util.format(locale.renderDirectoryParsing, path));
|
|
this.scandir({
|
|
path: path,
|
|
fileAction: function(fileFullPath, fileRelativePath, nextFile, fileStat) {
|
|
var data, file, options;
|
|
|
|
data = {
|
|
fullPath: fileFullPath,
|
|
relativePath: fileRelativePath
|
|
};
|
|
options = {
|
|
stat: fileStat
|
|
};
|
|
file = createFunction(data, options);
|
|
filesToLoad.add(file);
|
|
return nextFile();
|
|
},
|
|
next: function(err) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
docpad.log('debug', util.format(locale.renderDirectoryParsed, path));
|
|
return docpad.loadFiles({
|
|
collection: filesToLoad
|
|
}, function(err) {
|
|
return next(err);
|
|
});
|
|
}
|
|
});
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.getPlugin = function(pluginName) {
|
|
return this.loadedPlugins[pluginName];
|
|
};
|
|
|
|
DocPad.prototype.hasPlugins = function() {
|
|
return typeChecker.isEmptyObject(this.loadedPlugins) === false;
|
|
};
|
|
|
|
DocPad.prototype.loadPlugins = function(next) {
|
|
var docpad, locale, snore, tasks,
|
|
_this = this;
|
|
|
|
docpad = this;
|
|
locale = this.getLocale();
|
|
this.slowPlugins = {};
|
|
snore = balUtil.createSnore(function() {
|
|
return docpad.log('notice', util.format(locale.pluginsSlow, Object.keys(docpad.slowPlugins).join(', ')));
|
|
});
|
|
tasks = new TaskGroup().setConfig({
|
|
concurrency: 0
|
|
}).once('complete', function(err) {
|
|
docpad.slowPlugins = {};
|
|
snore.clear();
|
|
return next(err);
|
|
});
|
|
(this.config.pluginsPaths || []).forEach(function(pluginsPath) {
|
|
var exists;
|
|
|
|
exists = safefs.existsSync(pluginsPath);
|
|
if (exists) {
|
|
return tasks.addTask(function(complete) {
|
|
return _this.loadPluginsIn(pluginsPath, complete);
|
|
});
|
|
}
|
|
});
|
|
(this.config.pluginPaths || []).forEach(function(pluginPath) {
|
|
var exists;
|
|
|
|
exists = safefs.existsSync(pluginPath);
|
|
if (exists) {
|
|
return tasks.addTask(function(complete) {
|
|
return _this.loadPlugin(pluginPath, complete);
|
|
});
|
|
}
|
|
});
|
|
tasks.run();
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.loadedPlugin = function(pluginName, next) {
|
|
var docpad, loaded;
|
|
|
|
docpad = this;
|
|
loaded = docpad.loadedPlugins[pluginName] != null;
|
|
next(null, loaded);
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.loadPlugin = function(fileFullPath, _next) {
|
|
var config, docpad, enabled, loader, locale, next, pluginName;
|
|
|
|
docpad = this;
|
|
config = this.getConfig();
|
|
locale = this.getLocale();
|
|
next = function(err) {
|
|
delete docpad.slowPlugins[pluginName];
|
|
return _next(err);
|
|
};
|
|
loader = new PluginLoader({
|
|
dirPath: fileFullPath,
|
|
docpad: this,
|
|
BasePlugin: BasePlugin
|
|
});
|
|
pluginName = loader.pluginName;
|
|
enabled = (config.enableUnlistedPlugins && (config.enabledPlugins[pluginName] != null) === false) || config.enabledPlugins[pluginName] === true;
|
|
if (docpad.loadedPlugins[pluginName] != null) {
|
|
docpad.loadedPlugins[pluginName].setConfig();
|
|
return _next();
|
|
}
|
|
docpad.slowPlugins[pluginName] = true;
|
|
if (!enabled) {
|
|
docpad.log('debug', util.format(locale.pluginSkipped, pluginName));
|
|
return next();
|
|
} else {
|
|
docpad.log('debug', util.format(locale.pluginLoading, pluginName));
|
|
loader.exists(function(err, exists) {
|
|
if (err || !exists) {
|
|
return next(err);
|
|
}
|
|
return loader.unsupported(function(err, unsupported) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
if (unsupported) {
|
|
if (unsupported === 'version' && config.skipUnsupportedPlugins === false) {
|
|
docpad.log('warn', util.format(locale.pluginContinued, pluginName));
|
|
} else {
|
|
if (unsupported === 'type') {
|
|
docpad.log('debug', util.format(locale.pluginSkippedDueTo, pluginName, unsupported));
|
|
} else {
|
|
docpad.log('warn', util.format(locale.pluginSkippedDueTo, pluginName, unsupported));
|
|
}
|
|
return next();
|
|
}
|
|
}
|
|
return loader.load(function(err) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
return loader.create({}, function(err, pluginInstance) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
docpad.loadedPlugins[loader.pluginName] = pluginInstance;
|
|
docpad.log('debug', util.format(locale.pluginLoaded, pluginName));
|
|
return next();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
}
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.loadPluginsIn = function(pluginsPath, next) {
|
|
var docpad, locale;
|
|
|
|
docpad = this;
|
|
locale = this.getLocale();
|
|
docpad.log('debug', util.format(locale.pluginsLoadingFor, pluginsPath));
|
|
this.scandir({
|
|
path: pluginsPath,
|
|
fileAction: false,
|
|
dirAction: function(fileFullPath, fileRelativePath, _nextFile) {
|
|
var nextFile, pluginName;
|
|
|
|
pluginName = pathUtil.basename(fileFullPath);
|
|
if (fileFullPath === pluginsPath) {
|
|
return _nextFile(null, false);
|
|
}
|
|
nextFile = function(err, skip) {
|
|
if (err) {
|
|
docpad.warn(util.format(locale.pluginFailedToLoad, pluginName, fileFullPath) + '\n' + locale.errorFollows, err);
|
|
}
|
|
return _nextFile(null, skip);
|
|
};
|
|
return docpad.loadPlugin(fileFullPath, function(err) {
|
|
return nextFile(err, true);
|
|
});
|
|
},
|
|
next: function(err) {
|
|
docpad.log('debug', util.format(locale.pluginsLoadedFor, pluginsPath));
|
|
return next(err);
|
|
}
|
|
});
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.compareVersion = function() {
|
|
var docpad, locale;
|
|
|
|
if (!this.config.checkVersion) {
|
|
return this;
|
|
}
|
|
docpad = this;
|
|
locale = this.getLocale();
|
|
balUtil.packageCompare({
|
|
local: this.packagePath,
|
|
remote: this.config.latestPackageUrl,
|
|
newVersionCallback: function(details) {
|
|
docpad.notify(locale.upgradeNotification);
|
|
return docpad.log('notice', util.format(locale.upgradeDetails, details.local.version, details.remote.version, details.local.upgradeUrl || details.remote.installUrl || details.remote.homepage));
|
|
}
|
|
});
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.getExchange = function(next) {
|
|
var exchangeUrl;
|
|
|
|
if (!typeChecker.isEmptyObject(this.exchange)) {
|
|
return next(null, this.exchange);
|
|
}
|
|
exchangeUrl = this.config.exchangeUrl + '?version=' + this.version;
|
|
this.loadConfigUrl(exchangeUrl, function(err, parsedData) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
this.exchange = parsedData;
|
|
return next(null, parsedData);
|
|
});
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.installSkeleton = function(skeletonModel, destinationPath, next) {
|
|
var docpad, packagePath, repoConfig;
|
|
|
|
docpad = this;
|
|
packagePath = pathUtil.join(destinationPath, 'package.json');
|
|
repoConfig = {
|
|
path: destinationPath,
|
|
url: skeletonModel.get('repo'),
|
|
branch: skeletonModel.get('branch'),
|
|
remote: 'skeleton',
|
|
output: true,
|
|
next: function(err) {
|
|
if (err) {
|
|
return docpad.error(err);
|
|
}
|
|
return docpad.initNodeModules({
|
|
path: destinationPath,
|
|
output: true,
|
|
next: function(err) {
|
|
if (err) {
|
|
return docpad.error(err);
|
|
}
|
|
return next();
|
|
}
|
|
});
|
|
}
|
|
};
|
|
safefs.ensurePath(destinationPath, function(err) {
|
|
if (err) {
|
|
return docpad.error(err);
|
|
}
|
|
return docpad.initGitRepo(repoConfig);
|
|
});
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.loadFiles = function(opts, next) {
|
|
var collection, database, docpad, locale, tasks;
|
|
|
|
if (opts == null) {
|
|
opts = {};
|
|
}
|
|
docpad = this;
|
|
locale = this.getLocale();
|
|
database = this.getDatabase();
|
|
collection = opts.collection;
|
|
docpad.log('debug', util.format(locale.loadingFiles, collection.length));
|
|
tasks = new TaskGroup().setConfig({
|
|
concurrency: 0
|
|
}).once('complete', function(err) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
return docpad.emitSync('loadAfter', {
|
|
collection: collection
|
|
}, function(err) {
|
|
docpad.log('debug', util.format(locale.loadedFiles, collection.length));
|
|
return next();
|
|
});
|
|
});
|
|
collection.forEach(function(file) {
|
|
return tasks.addTask(function(complete) {
|
|
var fileRelativePath;
|
|
|
|
fileRelativePath = file.get('relativePath');
|
|
docpad.log('debug', util.format(locale.loadingFile, fileRelativePath));
|
|
return file.load(function(err) {
|
|
var fileIgnored, fileParse;
|
|
|
|
if (err) {
|
|
docpad.warn(util.format(locale.loadingFileFailed, fileRelativePath) + "\n" + locale.errorFollows, err);
|
|
return complete();
|
|
}
|
|
fileIgnored = file.get('ignored');
|
|
fileParse = file.get('parse');
|
|
if (fileIgnored || ((fileParse != null) && !fileParse)) {
|
|
docpad.log('info', util.format(locale.loadingFileIgnored, fileRelativePath));
|
|
collection.remove(file);
|
|
return complete();
|
|
} else {
|
|
docpad.log('debug', util.format(locale.loadedFile, fileRelativePath));
|
|
}
|
|
database.add(file);
|
|
return complete();
|
|
});
|
|
});
|
|
});
|
|
docpad.emitSync('loadBefore', {
|
|
collection: collection
|
|
}, function(err) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
return tasks.run();
|
|
});
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.contextualizeFiles = function(opts, next) {
|
|
var collection, docpad, locale, tasks, templateData, _ref1;
|
|
|
|
if (opts == null) {
|
|
opts = {};
|
|
}
|
|
docpad = this;
|
|
locale = this.getLocale();
|
|
collection = opts.collection, templateData = opts.templateData;
|
|
docpad.log('debug', util.format(locale.contextualizingFiles, collection.length));
|
|
tasks = new TaskGroup().setConfig({
|
|
concurrency: 0
|
|
}).once('complete', function(err) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
return docpad.emitSync('contextualizeAfter', {
|
|
collection: collection
|
|
}, function(err) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
docpad.log('debug', util.format(locale.contextualizedFiles, collection.length));
|
|
return next();
|
|
});
|
|
});
|
|
if ((_ref1 = opts.progress) != null) {
|
|
_ref1.step('contextualizeFiles').total(collection.length);
|
|
}
|
|
collection.forEach(function(file, index) {
|
|
return tasks.addTask(function(complete) {
|
|
return file.contextualize(function(err) {
|
|
var _ref2;
|
|
|
|
if ((_ref2 = opts.progress) != null) {
|
|
_ref2.tick();
|
|
}
|
|
return complete(err);
|
|
});
|
|
});
|
|
});
|
|
docpad.emitSync('contextualizeBefore', {
|
|
collection: collection,
|
|
templateData: templateData
|
|
}, function(err) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
return tasks.run();
|
|
});
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.renderFiles = function(opts, next) {
|
|
var collection, docpad, initialCollection, locale, renderCollection, renderFile, renderPasses, subsequentCollection, tasks, templateData, _i, _results,
|
|
_this = this;
|
|
|
|
if (opts == null) {
|
|
opts = {};
|
|
}
|
|
docpad = this;
|
|
locale = this.getLocale();
|
|
collection = opts.collection, templateData = opts.templateData, renderPasses = opts.renderPasses;
|
|
docpad.log('debug', util.format(locale.renderingFiles, collection.length));
|
|
tasks = new TaskGroup().once('complete', function(err) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
return docpad.emitSync('renderAfter', {
|
|
collection: collection
|
|
}, function(err) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
docpad.log('debug', util.format(locale.renderedFiles, collection.length));
|
|
return next();
|
|
});
|
|
});
|
|
renderFile = function(fileToRender, next) {
|
|
var dynamic, relativePath, render;
|
|
|
|
dynamic = fileToRender.get('dynamic');
|
|
render = fileToRender.get('render');
|
|
relativePath = fileToRender.get('relativePath');
|
|
if (dynamic || ((render != null) && !render) || !relativePath || (fileToRender.render != null) === false) {
|
|
next();
|
|
} else {
|
|
fileToRender.render({
|
|
templateData: templateData
|
|
}, next);
|
|
}
|
|
return fileToRender;
|
|
};
|
|
renderCollection = function(collectionToRender, _arg, next) {
|
|
var renderPass, step, subTasks, _ref1;
|
|
|
|
renderPass = _arg.renderPass;
|
|
subTasks = new TaskGroup().setConfig({
|
|
concurrency: 0
|
|
}).once('complete', next);
|
|
step = "renderFiles (pass " + renderPass + ")";
|
|
if ((_ref1 = opts.progress) != null) {
|
|
_ref1.step(step).total(collectionToRender.length);
|
|
}
|
|
collectionToRender.forEach(function(file) {
|
|
return subTasks.addTask(function(complete) {
|
|
return renderFile(file, function(err) {
|
|
var _ref2;
|
|
|
|
if ((_ref2 = opts.progress) != null) {
|
|
_ref2.tick();
|
|
}
|
|
return complete(err);
|
|
});
|
|
});
|
|
});
|
|
subTasks.run();
|
|
return collectionToRender;
|
|
};
|
|
initialCollection = collection.findAll({
|
|
'referencesOthers': false
|
|
});
|
|
subsequentCollection = null;
|
|
tasks.addTask(function(complete) {
|
|
return renderCollection(initialCollection, {
|
|
renderPass: 1
|
|
}, function(err) {
|
|
if (err) {
|
|
return complete(err);
|
|
}
|
|
subsequentCollection = collection.findAll({
|
|
'referencesOthers': true
|
|
});
|
|
return renderCollection(subsequentCollection, {
|
|
renderPass: 2
|
|
}, complete);
|
|
});
|
|
});
|
|
if (renderPasses > 1) {
|
|
(function() {
|
|
_results = [];
|
|
for (var _i = 3; 3 <= renderPasses ? _i <= renderPasses : _i >= renderPasses; 3 <= renderPasses ? _i++ : _i--){ _results.push(_i); }
|
|
return _results;
|
|
}).apply(this).forEach(function(renderPass) {
|
|
return tasks.addTask(function(complete) {
|
|
return renderCollection(subsequentCollection, {
|
|
renderPass: renderPass
|
|
}, complete);
|
|
});
|
|
});
|
|
}
|
|
docpad.emitSync('renderBefore', {
|
|
collection: collection,
|
|
templateData: templateData
|
|
}, function(err) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
return tasks.run();
|
|
});
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.writeFiles = function(opts, next) {
|
|
var collection, docpad, locale, tasks, templateData, _ref1,
|
|
_this = this;
|
|
|
|
if (opts == null) {
|
|
opts = {};
|
|
}
|
|
docpad = this;
|
|
locale = this.getLocale();
|
|
collection = opts.collection, templateData = opts.templateData;
|
|
docpad.log('debug', util.format(locale.writingFiles, collection.length));
|
|
tasks = new TaskGroup().setConfig({
|
|
concurrency: 0
|
|
}).once('complete', function(err) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
return docpad.emitSync('writeAfter', {
|
|
collection: collection
|
|
}, function(err) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
docpad.log('debug', util.format(locale.wroteFiles, collection.length));
|
|
return next();
|
|
});
|
|
});
|
|
if ((_ref1 = opts.progress) != null) {
|
|
_ref1.step('writeFiles').total(collection.length);
|
|
}
|
|
collection.forEach(function(file, index) {
|
|
return tasks.addTask(function(complete) {
|
|
var dynamic, err, finish, relativePath, write;
|
|
|
|
dynamic = file.get('dynamic');
|
|
write = file.get('write');
|
|
relativePath = file.get('relativePath');
|
|
finish = function(err) {
|
|
var _ref2;
|
|
|
|
if ((_ref2 = opts.progress) != null) {
|
|
_ref2.tick();
|
|
}
|
|
return complete(err);
|
|
};
|
|
if (dynamic || ((write != null) && !write) || !relativePath) {
|
|
return finish();
|
|
} else if (file.writeRendered != null) {
|
|
return file.writeRendered(finish);
|
|
} else if (file.write != null) {
|
|
return file.write(finish);
|
|
} else {
|
|
err = new Error(locale.unknownModelInCollection);
|
|
return finish(err);
|
|
}
|
|
});
|
|
});
|
|
docpad.emitSync('writeBefore', {
|
|
collection: collection,
|
|
templateData: templateData
|
|
}, function(err) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
return tasks.run();
|
|
});
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.action = function(action, opts, next) {
|
|
var actions, docpad, forward, locale, runner, tasks, _ref1,
|
|
_this = this;
|
|
|
|
_ref1 = balUtil.extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
|
|
docpad = this;
|
|
runner = this.getActionRunner();
|
|
locale = this.getLocale();
|
|
if (typeChecker.isArray(action)) {
|
|
actions = action;
|
|
} else {
|
|
actions = action.split(/[,\s]+/g);
|
|
}
|
|
actions = _.uniq(_.compact(actions));
|
|
if (actions.length === 1) {
|
|
action = actions[0];
|
|
} else {
|
|
tasks = new TaskGroup().once('complete', function(err) {
|
|
return next(err);
|
|
});
|
|
actions.forEach(function(action) {
|
|
return tasks.addTask(function(complete) {
|
|
return docpad.action(action, opts, complete);
|
|
});
|
|
});
|
|
tasks.run();
|
|
return docpad;
|
|
}
|
|
this.log('debug', util.format(locale.actionStart, action));
|
|
if (next == null) {
|
|
next = function(err) {
|
|
if (err) {
|
|
return docpad.fatal(err);
|
|
}
|
|
};
|
|
}
|
|
forward = function() {
|
|
var args;
|
|
|
|
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
|
_this.log('debug', util.format(locale.actionFinished, action));
|
|
return process.nextTick(function() {
|
|
return next.apply(null, args);
|
|
});
|
|
};
|
|
runner.addTask(function(complete) {
|
|
var fn;
|
|
|
|
fn = docpad[action];
|
|
if (!fn) {
|
|
return complete(new Error(util.format(locale.actionNonexistant, action)));
|
|
}
|
|
docpad.track(action);
|
|
return fn(opts, function() {
|
|
var args;
|
|
|
|
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
|
forward.apply(null, args);
|
|
return complete();
|
|
});
|
|
});
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.generatePrepare = function(opts, next) {
|
|
var config, docpad, locale, tasks, _ref1;
|
|
|
|
_ref1 = balUtil.extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
|
|
docpad = this;
|
|
config = this.getConfig();
|
|
locale = this.getLocale();
|
|
docpad.generating = true;
|
|
docpad.log('info', locale.renderGenerating);
|
|
docpad.notify((new Date()).toLocaleTimeString(), {
|
|
title: locale.renderGeneratingNotification
|
|
});
|
|
tasks = new TaskGroup().once('complete', next);
|
|
if (opts.reset === true) {
|
|
if (!docpad.hasPlugins()) {
|
|
docpad.log('warn', locale.renderNoPlugins);
|
|
}
|
|
tasks.addTask(function(complete) {
|
|
return safefs.exists(config.srcPath, function(exists) {
|
|
var err;
|
|
|
|
if (exists === false) {
|
|
err = new Error(locale.renderNonexistant);
|
|
return complete(err);
|
|
} else {
|
|
return complete();
|
|
}
|
|
});
|
|
});
|
|
tasks.addTask(function(complete) {
|
|
return docpad.resetCollections(complete);
|
|
});
|
|
}
|
|
tasks.addTask(function(complete) {
|
|
return docpad.emitSync('generateBefore', {
|
|
reset: opts.reset,
|
|
server: docpad.getServer()
|
|
}, complete);
|
|
});
|
|
tasks.run();
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.generateParse = function(opts, next) {
|
|
var config, database, docpad, locale, _ref1;
|
|
|
|
_ref1 = balUtil.extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
|
|
docpad = this;
|
|
database = this.getDatabase();
|
|
config = this.getConfig();
|
|
locale = this.getLocale();
|
|
this.emitSync('parseBefore', {}, function(err) {
|
|
var tasks;
|
|
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
docpad.log('debug', locale.renderParsing);
|
|
tasks = new TaskGroup().setConfig({
|
|
concurrency: 0
|
|
}).once('complete', function(err) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
return docpad.emitSync('parseAfter', {}, function(err) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
docpad.log('debug', locale.renderParsed);
|
|
return next(err);
|
|
});
|
|
});
|
|
config.documentsPaths.forEach(function(documentsPath) {
|
|
return tasks.addTask(function(complete) {
|
|
return docpad.parseDocumentDirectory({
|
|
path: documentsPath,
|
|
collection: database
|
|
}, complete);
|
|
});
|
|
});
|
|
config.filesPaths.forEach(function(filesPath) {
|
|
return tasks.addTask(function(complete) {
|
|
return docpad.parseFileDirectory({
|
|
path: filesPath,
|
|
collection: database
|
|
}, complete);
|
|
});
|
|
});
|
|
config.layoutsPaths.forEach(function(layoutsPath) {
|
|
return tasks.addTask(function(complete) {
|
|
return docpad.parseDocumentDirectory({
|
|
path: layoutsPath,
|
|
collection: database
|
|
}, complete);
|
|
});
|
|
});
|
|
return tasks.run();
|
|
});
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.generateRender = function(opts, next) {
|
|
var docpad, _ref1;
|
|
|
|
_ref1 = balUtil.extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
|
|
docpad = this;
|
|
opts.templateData || (opts.templateData = this.getTemplateData());
|
|
opts.collection || (opts.collection = this.getDatabase());
|
|
opts.renderPasses || (opts.renderPasses = this.getConfig().renderPasses);
|
|
balUtil.flow({
|
|
object: docpad,
|
|
action: 'contextualizeFiles renderFiles writeFiles',
|
|
args: [opts],
|
|
next: function(err) {
|
|
return next(err);
|
|
}
|
|
});
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.generatePostpare = function(opts, next) {
|
|
var collection, database, docpad, locale, _ref1;
|
|
|
|
_ref1 = balUtil.extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
|
|
docpad = this;
|
|
locale = this.getLocale();
|
|
database = this.getDatabase();
|
|
collection = opts.collection || database;
|
|
docpad.generating = false;
|
|
docpad.generateEnded = new Date();
|
|
docpad.databaseCache = null;
|
|
docpad.emitSync('generateAfter', {
|
|
server: docpad.getServer()
|
|
}, function(err) {
|
|
var howMany, seconds, _ref2;
|
|
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
seconds = (docpad.generateEnded - docpad.generateStarted) / 1000;
|
|
howMany = collection === database ? "all " + collection.length : collection.length;
|
|
if ((_ref2 = opts.progress) != null) {
|
|
_ref2.finish();
|
|
}
|
|
docpad.log('info', util.format(locale.renderGenerated, howMany, seconds));
|
|
docpad.notify((new Date()).toLocaleTimeString(), {
|
|
title: locale.renderGeneratedNotification
|
|
});
|
|
return next();
|
|
});
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.generateStarted = null;
|
|
|
|
DocPad.prototype.generateEnded = null;
|
|
|
|
DocPad.prototype.generating = false;
|
|
|
|
DocPad.prototype.generate = function(opts, next) {
|
|
var config, docpad, finish, locale, _ref1, _ref2, _ref3, _ref4;
|
|
|
|
_ref1 = balUtil.extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
|
|
docpad = this;
|
|
config = this.getConfig();
|
|
locale = this.getLocale();
|
|
if ((_ref2 = opts.reset) == null) {
|
|
opts.reset = true;
|
|
}
|
|
if (((_ref3 = opts.collection) != null ? _ref3.length : void 0) === 0) {
|
|
return next();
|
|
}
|
|
if (config.prompts && this.getLogLevel() === 6) {
|
|
if ((_ref4 = opts.progress) == null) {
|
|
opts.progress = require('progressbar').create();
|
|
}
|
|
docpad.getLoggers().console.unpipe(process.stdout);
|
|
}
|
|
finish = function(err) {
|
|
if (opts.progress) {
|
|
opts.progress.finish();
|
|
opts.progress = null;
|
|
docpad.getLoggers().console.pipe(process.stdout);
|
|
}
|
|
return next(err);
|
|
};
|
|
if ((opts.collection != null) === false && opts.reset === false) {
|
|
docpad.generatePrepare(opts, function(err) {
|
|
var database, filesToReload;
|
|
|
|
if (err) {
|
|
return finish(err);
|
|
}
|
|
database = docpad.getDatabase();
|
|
filesToReload = opts.filesToReload || new FilesCollection();
|
|
filesToReload.add(database.findAll({
|
|
mtime: {
|
|
$gte: docpad.generateStarted
|
|
}
|
|
}).models);
|
|
docpad.generateStarted = new Date();
|
|
return docpad.loadFiles({
|
|
collection: filesToReload
|
|
}, function(err) {
|
|
var allStandalone, filesToRender;
|
|
|
|
if (err) {
|
|
return finish(err);
|
|
}
|
|
filesToRender = opts.filesToRender || new FilesCollection();
|
|
filesToRender.on('add', function(fileToRender) {
|
|
if (fileToRender.get('isLayout')) {
|
|
return filesToRender.add(database.findAll({
|
|
layoutId: fileToRender.id
|
|
}).models);
|
|
}
|
|
});
|
|
allStandalone = true;
|
|
filesToReload.forEach(function(fileToReload) {
|
|
if (fileToReload.get('standalone') !== true) {
|
|
allStandalone = false;
|
|
return false;
|
|
}
|
|
});
|
|
if (allStandalone === false) {
|
|
filesToRender.add(database.findAll({
|
|
referencesOthers: true
|
|
}).models);
|
|
}
|
|
filesToRender.add(filesToReload.models);
|
|
return docpad.generateRender({
|
|
collection: filesToRender
|
|
}, function(err) {
|
|
if (err) {
|
|
return finish(err);
|
|
}
|
|
return docpad.generatePostpare({
|
|
collection: filesToRender
|
|
}, function(err) {
|
|
return finish(err);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
} else {
|
|
docpad.generateStarted = new Date();
|
|
balUtil.flow({
|
|
object: docpad,
|
|
action: 'generatePrepare generateParse generateRender generatePostpare',
|
|
args: [opts],
|
|
next: function(err) {
|
|
return finish(err);
|
|
}
|
|
});
|
|
}
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.flowDocument = function(document, opts, next) {
|
|
var _ref1;
|
|
|
|
_ref1 = balUtil.extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
|
|
balUtil.flow({
|
|
object: document,
|
|
action: opts.action,
|
|
args: [opts],
|
|
next: function(err) {
|
|
return typeof next === "function" ? next(err, document) : void 0;
|
|
}
|
|
});
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.loadDocument = function(document, opts, next) {
|
|
var _ref1;
|
|
|
|
_ref1 = balUtil.extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
|
|
opts.action || (opts.action = 'load contextualize');
|
|
this.flowDocument(document, opts, next);
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.loadAndRenderDocument = function(document, opts, next) {
|
|
var _ref1;
|
|
|
|
_ref1 = balUtil.extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
|
|
opts.action || (opts.action = 'load contextualize render');
|
|
this.flowDocument(document, opts, function(err) {
|
|
var result;
|
|
|
|
result = document.getOutContent();
|
|
return typeof next === "function" ? next(err, result, document) : void 0;
|
|
});
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.renderDocument = function(document, opts, next) {
|
|
var _ref1;
|
|
|
|
_ref1 = balUtil.extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
|
|
document.render(opts, next);
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.renderPath = function(path, opts, next) {
|
|
var attributes, document, _ref1;
|
|
|
|
_ref1 = balUtil.extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
|
|
attributes = extendr.extend({
|
|
fullPath: path
|
|
}, opts.attributes);
|
|
document = this.ensureDocument(attributes);
|
|
this.loadAndRenderDocument(document, opts, next);
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.renderData = function(content, opts, next) {
|
|
var attributes, document, _ref1;
|
|
|
|
_ref1 = balUtil.extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
|
|
attributes = extendr.extend({
|
|
filename: opts.filename,
|
|
data: content
|
|
}, opts.attributes);
|
|
document = this.createDocument(attributes);
|
|
this.loadAndRenderDocument(document, opts, next);
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.renderText = function(text, opts, next) {
|
|
var attributes, document, _ref1, _ref2;
|
|
|
|
_ref1 = balUtil.extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
|
|
if ((_ref2 = opts.actions) == null) {
|
|
opts.actions = ['renderExtensions', 'renderDocument'];
|
|
}
|
|
attributes = extendr.extend({
|
|
filename: opts.filename,
|
|
data: text,
|
|
body: text,
|
|
content: text
|
|
}, opts.attributes);
|
|
document = this.createDocument(attributes);
|
|
balUtil.flow({
|
|
object: document,
|
|
action: 'normalize contextualize render',
|
|
args: [opts],
|
|
next: function(err) {
|
|
var result;
|
|
|
|
result = document.getOutContent();
|
|
return next(err, result, document);
|
|
}
|
|
});
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.render = function(opts, next) {
|
|
var err, locale, path, _ref1;
|
|
|
|
_ref1 = balUtil.extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
|
|
locale = this.getLocale();
|
|
if (opts.document) {
|
|
this.renderDocument(opts.document, opts, next);
|
|
} else if (opts.data) {
|
|
this.renderData(opts.data, opts, next);
|
|
} else if (opts.text) {
|
|
this.renderText(opts.text, opts, next);
|
|
} else {
|
|
path = opts.path || opts.fullPath || opts.filename || null;
|
|
if (path) {
|
|
this.renderPath(path, opts, next);
|
|
} else {
|
|
err = new Error(locale.renderInvalidOptions);
|
|
return next(err);
|
|
}
|
|
}
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.watch = function(opts, next) {
|
|
var changeHandler, closeWatchers, config, database, docpad, locale, performGenerate, queueRegeneration, regenerateTimer, resetWatchers, watchers, _ref1;
|
|
|
|
_ref1 = balUtil.extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
|
|
docpad = this;
|
|
config = this.getConfig();
|
|
locale = this.getLocale();
|
|
database = this.getDatabase();
|
|
watchers = [];
|
|
closeWatchers = function() {
|
|
var watcher, _i, _len;
|
|
|
|
for (_i = 0, _len = watchers.length; _i < _len; _i++) {
|
|
watcher = watchers[_i];
|
|
watcher.close();
|
|
watcher = null;
|
|
}
|
|
return watchers = [];
|
|
};
|
|
resetWatchers = function(next) {
|
|
var regeneratePaths, reloadPaths, srcPath, tasks;
|
|
|
|
closeWatchers();
|
|
tasks = new TaskGroup().setConfig({
|
|
concurrency: 0
|
|
}).once('complete', next);
|
|
reloadPaths = _.union(config.reloadPaths, config.configPaths);
|
|
tasks.addTask(function(complete) {
|
|
return docpad.watchdir({
|
|
paths: reloadPaths,
|
|
listeners: {
|
|
'log': docpad.log,
|
|
'error': docpad.error,
|
|
'change': function() {
|
|
docpad.log('info', util.format(locale.watchReloadChange, new Date().toLocaleTimeString()));
|
|
return docpad.action('load', function(err) {
|
|
if (err) {
|
|
return docpad.fatal(err);
|
|
}
|
|
return performGenerate({
|
|
reset: true
|
|
});
|
|
});
|
|
}
|
|
},
|
|
next: function(err, _watchers) {
|
|
var watcher, _i, _len;
|
|
|
|
if (err) {
|
|
docpad.log('warn', "Watching the reload paths has failed:", reloadPaths, err);
|
|
return complete();
|
|
}
|
|
for (_i = 0, _len = _watchers.length; _i < _len; _i++) {
|
|
watcher = _watchers[_i];
|
|
watchers.push(watcher);
|
|
}
|
|
return complete();
|
|
}
|
|
});
|
|
});
|
|
regeneratePaths = config.regeneratePaths;
|
|
tasks.addTask(function(complete) {
|
|
return docpad.watchdir({
|
|
paths: regeneratePaths,
|
|
listeners: {
|
|
'log': docpad.log,
|
|
'error': docpad.error,
|
|
'change': function() {
|
|
return performGenerate({
|
|
reset: true
|
|
});
|
|
}
|
|
},
|
|
next: function(err, _watchers) {
|
|
var watcher, _i, _len;
|
|
|
|
if (err) {
|
|
docpad.log('warn', "Watching the regenerate paths has failed:", regeneratePaths, err);
|
|
return complete();
|
|
}
|
|
for (_i = 0, _len = _watchers.length; _i < _len; _i++) {
|
|
watcher = _watchers[_i];
|
|
watchers.push(watcher);
|
|
}
|
|
return complete();
|
|
}
|
|
});
|
|
});
|
|
srcPath = config.srcPath;
|
|
tasks.addTask(function(complete) {
|
|
return docpad.watchdir({
|
|
path: srcPath,
|
|
listeners: {
|
|
'log': docpad.log,
|
|
'error': docpad.error,
|
|
'change': changeHandler
|
|
},
|
|
next: function(err, watcher) {
|
|
if (err) {
|
|
docpad.log('warn', "Watching the src path has failed:", srcPath, err);
|
|
return complete();
|
|
}
|
|
watchers.push(watcher);
|
|
return complete();
|
|
}
|
|
});
|
|
});
|
|
return tasks.run();
|
|
};
|
|
regenerateTimer = null;
|
|
queueRegeneration = function() {
|
|
if (regenerateTimer) {
|
|
clearTimeout(regenerateTimer);
|
|
regenerateTimer = null;
|
|
}
|
|
return regenerateTimer = setTimeout(performGenerate, config.regenerateDelay);
|
|
};
|
|
performGenerate = function(opts) {
|
|
var _ref2;
|
|
|
|
opts || (opts = {});
|
|
if ((_ref2 = opts.reset) == null) {
|
|
opts.reset = false;
|
|
}
|
|
docpad.log(util.format(locale.watchRegenerating, new Date().toLocaleTimeString()));
|
|
return docpad.action('generate', opts, function(err) {
|
|
if (err) {
|
|
docpad.error(err);
|
|
}
|
|
return docpad.log(util.format(locale.watchRegenerated, new Date().toLocaleTimeString()));
|
|
});
|
|
};
|
|
changeHandler = function(changeType, filePath, fileCurrentStat, filePreviousStat) {
|
|
var file, isDirectory, isIgnored;
|
|
|
|
docpad.log('debug', util.format(locale.watchChange, new Date().toLocaleTimeString()), changeType, filePath);
|
|
isIgnored = docpad.isIgnoredPath(filePath);
|
|
if (isIgnored) {
|
|
docpad.log('debug', util.format(locale.watchIgnoredChange, new Date().toLocaleTimeString()), filePath);
|
|
return;
|
|
}
|
|
isDirectory = (fileCurrentStat || filePreviousStat).isDirectory();
|
|
if (isDirectory) {
|
|
docpad.log('debug', util.format(locale.watchDirectoryChange, new Date().toLocaleTimeString()), filePath);
|
|
return;
|
|
}
|
|
if (fileCurrentStat != null) {
|
|
fileCurrentStat.mtime = new Date();
|
|
}
|
|
file = docpad.ensureFileOrDocument({
|
|
fullPath: filePath
|
|
}, {
|
|
stat: fileCurrentStat
|
|
});
|
|
if (changeType === 'update') {
|
|
file.setStat(fileCurrentStat);
|
|
}
|
|
if (changeType === 'delete') {
|
|
database.remove(file);
|
|
return file["delete"](function(err) {
|
|
if (err) {
|
|
return docpad.error(err);
|
|
}
|
|
return queueRegeneration();
|
|
});
|
|
} else if (changeType === 'create' || changeType === 'update') {
|
|
return queueRegeneration();
|
|
}
|
|
};
|
|
docpad.log(locale.watchStart);
|
|
resetWatchers(function(err) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
docpad.log(locale.watchStarted);
|
|
return next();
|
|
});
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.run = function(opts, next) {
|
|
var destinationPath, docpad, locale, runDocpad, srcPath, _ref1;
|
|
|
|
_ref1 = balUtil.extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
|
|
docpad = this;
|
|
srcPath = this.config.srcPath;
|
|
destinationPath = this.config.rootPath;
|
|
locale = this.getLocale();
|
|
runDocpad = function() {
|
|
return balUtil.flow({
|
|
object: docpad,
|
|
action: 'server generate watch',
|
|
args: [opts],
|
|
next: function(err) {
|
|
return next(err);
|
|
}
|
|
});
|
|
};
|
|
if (safefs.existsSync(srcPath)) {
|
|
runDocpad();
|
|
} else {
|
|
safefs.readdir(destinationPath, function(err, files) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
if (files.length) {
|
|
docpad.log('warn', "\n" + util.format(locale.skeletonNonexistant, destinationPath));
|
|
return next();
|
|
} else {
|
|
return docpad.skeleton(opts, function(err) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
return runDocpad();
|
|
});
|
|
}
|
|
});
|
|
}
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.skeleton = function(opts, next) {
|
|
var config, destinationPath, docpad, locale, selectSkeletonCallback, skeletonId, srcPath, useNoSkeleton, useSkeleton, _ref1;
|
|
|
|
_ref1 = balUtil.extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
|
|
docpad = this;
|
|
config = this.getConfig();
|
|
skeletonId = config.skeleton;
|
|
srcPath = config.srcPath;
|
|
destinationPath = config.rootPath;
|
|
selectSkeletonCallback = opts.selectSkeletonCallback || null;
|
|
locale = this.getLocale();
|
|
useSkeleton = function(skeletonModel) {
|
|
docpad.track('skeleton-use', {
|
|
skeletonId: skeletonModel.id
|
|
});
|
|
docpad.log('info', util.format(locale.skeletonInstall, skeletonModel.get('name'), destinationPath));
|
|
return docpad.installSkeleton(skeletonModel, destinationPath, function(err) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
return docpad.load(function(err) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
docpad.log('info', locale.skeletonInstalled);
|
|
return next(err);
|
|
});
|
|
});
|
|
};
|
|
useNoSkeleton = function() {
|
|
docpad.track('skeleton-use', {
|
|
skeletonId: 'none'
|
|
});
|
|
return safefs.ensurePath(srcPath, function(err) {
|
|
var tasks;
|
|
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
tasks = new TaskGroup().setConfig({
|
|
concurrency: 0
|
|
}).once('complete', next);
|
|
tasks.addTask(function(complete) {
|
|
return safefs.ensurePath(pathUtil.join(config.rootPath, 'node_modules'), complete);
|
|
});
|
|
tasks.addTask(function(complete) {
|
|
var data;
|
|
|
|
data = JSON.stringify({
|
|
name: 'no-skeleton.docpad',
|
|
version: '0.1.0',
|
|
description: 'New DocPad project without using a skeleton',
|
|
engines: {
|
|
node: '0.10',
|
|
npm: '1.2'
|
|
},
|
|
dependencies: {
|
|
docpad: '6.x'
|
|
},
|
|
main: 'node_modules/docpad/bin/docpad-server'
|
|
}, null, '\t');
|
|
return safefs.writeFile(pathUtil.join(config.rootPath, 'package.json'), data, complete);
|
|
});
|
|
tasks.addTask(function(complete) {
|
|
var data;
|
|
|
|
data = "# DocPad Configuration File\n# http://docpad.org/docs/config\n\n# Define the DocPad Configuration\ndocpadConfig = {\n # ...\n}\n\n# Export the DocPad Configuration\nmodule.exports = docpadConfig";
|
|
return safefs.writeFile(pathUtil.join(config.rootPath, 'docpad.coffee'), data, complete);
|
|
});
|
|
tasks.addTask(function(complete) {
|
|
return safefs.ensurePath(config.documentsPaths[0], complete);
|
|
});
|
|
tasks.addTask(function(complete) {
|
|
return safefs.ensurePath(config.layoutsPaths[0], complete);
|
|
});
|
|
tasks.addTask(function(complete) {
|
|
return safefs.ensurePath(config.filesPaths[0], complete);
|
|
});
|
|
return tasks.run();
|
|
});
|
|
};
|
|
safefs.exists(srcPath, function(exists) {
|
|
if (exists) {
|
|
docpad.log('warn', locale.skeletonExists);
|
|
return next();
|
|
}
|
|
docpad.track('skeleton-ask');
|
|
if (skeletonId) {
|
|
return useSkeleton();
|
|
} else {
|
|
return docpad.getSkeletons(function(err, skeletonsCollection) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
return selectSkeletonCallback(skeletonsCollection, function(err, skeletonModel) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
if ((skeletonModel != null) === false || skeletonModel.id === 'none') {
|
|
return useNoSkeleton();
|
|
} else {
|
|
return useSkeleton(skeletonModel);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
});
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.serveDocument = function(opts, next) {
|
|
var content, contentType, docpad, document, dynamic, err, req, res, templateData, _ref1;
|
|
|
|
_ref1 = balUtil.extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
|
|
document = opts.document, err = opts.err, req = opts.req, res = opts.res;
|
|
docpad = this;
|
|
if (!document) {
|
|
if (opts.statusCode != null) {
|
|
return res.send(opts.statusCode);
|
|
} else {
|
|
return next();
|
|
}
|
|
}
|
|
contentType = document.get('outContentType') || document.get('contentType');
|
|
res.setHeader('Content-Type', contentType);
|
|
dynamic = document.get('dynamic');
|
|
if (dynamic) {
|
|
templateData = extendr.extend({}, req.templateData || {}, {
|
|
req: req,
|
|
err: err
|
|
});
|
|
templateData = docpad.getTemplateData(templateData);
|
|
document.render({
|
|
templateData: templateData
|
|
}, function(err) {
|
|
var content;
|
|
|
|
content = document.getOutContent();
|
|
if (err) {
|
|
docpad.error(err);
|
|
return next(err);
|
|
} else {
|
|
if (opts.statusCode != null) {
|
|
return res.send(opts.statusCode, content);
|
|
} else {
|
|
return res.send(content);
|
|
}
|
|
}
|
|
});
|
|
} else {
|
|
content = document.getOutContent();
|
|
if (content) {
|
|
if (opts.statusCode != null) {
|
|
return res.send(opts.statusCode, content);
|
|
} else {
|
|
return res.send(content);
|
|
}
|
|
} else {
|
|
if (opts.statusCode != null) {
|
|
return res.send(opts.statusCode);
|
|
} else {
|
|
return next();
|
|
}
|
|
}
|
|
}
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.serverMiddlewareHeader = function(req, res, next) {
|
|
var docpad, tools;
|
|
|
|
docpad = this;
|
|
tools = res.get('X-Powered-By').split(/[,\s]+/g);
|
|
tools.push("DocPad v" + docpad.version);
|
|
tools = tools.join(',');
|
|
res.set('X-Powered-By', tools);
|
|
next();
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.serverMiddlewareRouter = function(req, res, next) {
|
|
var cleanUrl, database, docpad, file, url;
|
|
|
|
docpad = this;
|
|
if (docpad.generateEnded === null) {
|
|
docpad.once('generateAfter', function() {
|
|
return docpad.serverMiddlewareRouter(req, res, next);
|
|
});
|
|
return this;
|
|
}
|
|
database = docpad.getDatabaseCache();
|
|
cleanUrl = req.url.replace(/\?.*/, '');
|
|
file = docpad.getFileByUrl(req.url, {
|
|
collection: database
|
|
}) || docpad.getFileByUrl(cleanUrl, {
|
|
collection: database
|
|
});
|
|
if ((file != null) === false) {
|
|
return next();
|
|
}
|
|
url = file.get('url');
|
|
if ((url !== cleanUrl) && (url !== req.url)) {
|
|
return res.redirect(301, url);
|
|
}
|
|
docpad.serveDocument({
|
|
document: file,
|
|
req: req,
|
|
res: res,
|
|
next: next
|
|
});
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.serverMiddleware404 = function(req, res, next) {
|
|
var database, docpad, document;
|
|
|
|
docpad = this;
|
|
database = docpad.getDatabaseCache();
|
|
if (!database) {
|
|
return res.send(500);
|
|
}
|
|
document = database.findOne({
|
|
relativeOutPath: '404.html'
|
|
});
|
|
docpad.serveDocument({
|
|
document: document,
|
|
req: req,
|
|
res: res,
|
|
next: next,
|
|
statusCode: 404
|
|
});
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.serverMiddleware500 = function(err, req, res, next) {
|
|
var database, docpad, document;
|
|
|
|
docpad = this;
|
|
database = docpad.getDatabaseCache();
|
|
if (!database) {
|
|
return res.send(500);
|
|
}
|
|
document = database.findOne({
|
|
relativeOutPath: '500.html'
|
|
});
|
|
docpad.serveDocument({
|
|
document: document,
|
|
err: err,
|
|
req: req,
|
|
res: res,
|
|
next: next,
|
|
statusCode: 500
|
|
});
|
|
return this;
|
|
};
|
|
|
|
DocPad.prototype.server = function(opts, next) {
|
|
var config, docpad, express, finish, http, locale, port, serverExpress, serverHttp, startServer, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9;
|
|
|
|
http = null;
|
|
express = null;
|
|
_ref1 = balUtil.extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
|
|
docpad = this;
|
|
config = this.config;
|
|
locale = this.getLocale();
|
|
port = this.getPort();
|
|
serverExpress = null;
|
|
serverHttp = null;
|
|
if ((_ref2 = opts.middlewareBodyParser) == null) {
|
|
opts.middlewareBodyParser = (_ref3 = config.middlewareBodyParser) != null ? _ref3 : config.middlewareStandard;
|
|
}
|
|
if ((_ref4 = opts.middlewareMethodOverride) == null) {
|
|
opts.middlewareMethodOverride = (_ref5 = config.middlewareMethodOverride) != null ? _ref5 : config.middlewareStandard;
|
|
}
|
|
if ((_ref6 = opts.middlewareExpressRouter) == null) {
|
|
opts.middlewareExpressRouter = (_ref7 = config.middlewareExpressRouter) != null ? _ref7 : config.middlewareStandard;
|
|
}
|
|
if ((_ref8 = opts.middleware404) == null) {
|
|
opts.middleware404 = config.middleware404;
|
|
}
|
|
if ((_ref9 = opts.middleware500) == null) {
|
|
opts.middleware500 = config.middleware500;
|
|
}
|
|
finish = function(err) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
return docpad.emitSync('serverAfter', {
|
|
server: serverExpress,
|
|
serverExpress: serverExpress,
|
|
serverHttp: serverHttp,
|
|
express: express
|
|
}, function(err) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
return next();
|
|
});
|
|
};
|
|
startServer = function(next) {
|
|
serverHttp.once('error', function(err) {
|
|
if (err.message.indexOf('EADDRINUSE') !== -1) {
|
|
err = new Error(util.format(locale.serverInUse, port));
|
|
}
|
|
return next(err);
|
|
});
|
|
docpad.log('debug', util.format(locale.serverStart, port, config.outPath));
|
|
return serverHttp.listen(port, function() {
|
|
var address, serverHostname, serverLocation, serverPort;
|
|
|
|
address = serverHttp.address();
|
|
serverHostname = address.address === '0.0.0.0' ? 'localhost' : address.address;
|
|
serverPort = address.port;
|
|
serverLocation = "http://" + serverHostname + ":" + serverPort + "/";
|
|
docpad.log('info', util.format(locale.serverStarted, serverLocation, config.outPath));
|
|
return next();
|
|
});
|
|
};
|
|
docpad.emitSync('serverBefore', {}, function(err) {
|
|
var _ref10;
|
|
|
|
if (err) {
|
|
return finish(err);
|
|
}
|
|
_ref10 = docpad.getServer(true), serverExpress = _ref10.serverExpress, serverHttp = _ref10.serverHttp;
|
|
if (!serverExpress && !serverHttp) {
|
|
if (http == null) {
|
|
http = require('http');
|
|
}
|
|
if (express == null) {
|
|
express = require('express');
|
|
}
|
|
serverExpress = opts.serverExpress || express();
|
|
serverHttp = opts.serverHttp || http.createServer(serverExpress);
|
|
docpad.setServer({
|
|
serverExpress: serverExpress,
|
|
serverHttp: serverHttp
|
|
});
|
|
}
|
|
if (!config.extendServer) {
|
|
return startServer(finish);
|
|
} else {
|
|
if (express == null) {
|
|
express = require('express');
|
|
}
|
|
if (opts.middlewareBodyParser !== false) {
|
|
serverExpress.use(express.bodyParser());
|
|
}
|
|
if (opts.middlewareMethodOverride !== false) {
|
|
serverExpress.use(express.methodOverride());
|
|
}
|
|
docpad.emitSync('serverExtend', {
|
|
server: serverExpress,
|
|
serverExpress: serverExpress,
|
|
serverHttp: serverHttp,
|
|
express: express
|
|
}, function(err) {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
serverExpress.use(docpad.serverMiddlewareHeader);
|
|
if (opts.middlewareExpressRouter !== false) {
|
|
serverExpress.use(serverExpress.router);
|
|
}
|
|
serverExpress.use(docpad.serverMiddlewareRouter);
|
|
if (config.maxAge) {
|
|
serverExpress.use(express["static"](config.outPath, {
|
|
maxAge: config.maxAge
|
|
}));
|
|
} else {
|
|
serverExpress.use(express["static"](config.outPath));
|
|
}
|
|
if (opts.middleware404 !== false) {
|
|
serverExpress.use(docpad.serverMiddleware404);
|
|
}
|
|
if (opts.middleware500 !== false) {
|
|
return serverExpress.error(docpad.serverMiddleware500);
|
|
}
|
|
});
|
|
return startServer(finish);
|
|
}
|
|
});
|
|
return this;
|
|
};
|
|
|
|
return DocPad;
|
|
|
|
})(EventEmitterEnhanced);
|
|
|
|
module.exports = {
|
|
DocPad: DocPad,
|
|
queryEngine: queryEngine,
|
|
Backbone: Backbone,
|
|
createInstance: function() {
|
|
var args;
|
|
|
|
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
|
return (function(func, args, ctor) {
|
|
ctor.prototype = func.prototype;
|
|
var child = new ctor, result = func.apply(child, args);
|
|
return Object(result) === result ? result : child;
|
|
})(DocPad, args, function(){});
|
|
}
|
|
};
|