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.
 
 
 

3982 lines
124 KiB

// Generated by CoffeeScript 1.6.3
var Backbone, BasePlugin, CSON, Collection, DocPad, DocumentModel, ElementsCollection, EventEmitterEnhanced, Events, FileModel, FilesCollection, MetaCollection, Model, PluginLoader, QueryCollection, ScriptsCollection, StylesCollection, TaskGroup, View, ambi, balUtil, corePath, eachr, extendr, extractOptsAndCallback, lazyRequire, pathUtil, queryEngine, safefs, safeps, superAgent, typeChecker, util, _, _ref,
__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; },
__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; },
__slice = [].slice;
pathUtil = require('path');
lazyRequire = require('lazy-require').lazyRequire;
corePath = pathUtil.join(__dirname, '..', '..');
if ((__indexOf.call(process.argv, '--profile') >= 0)) {
debugger;
if (process.env.NODEFLY_KEY) {
console.log('Loading profiling tool: nodefly');
lazyRequire('nodefly', {
cwd: corePath
}, function(err, nodefly) {
if (err) {
return;
}
nodefly.profile(process.env.NODEFLY_KEY, 'docpad');
return console.log('Profiling with nodefly');
});
}
if (process.env.NODETIME_KEY) {
console.log('Loading profiling tool: nodetime');
lazyRequire('nodetime', {
cwd: corePath
}, function(err, nodetime) {
if (err) {
return;
}
nodetime.profile({
accountKey: process.env.NODETIME_KEY,
appName: 'DocPad'
});
return console.log('Profiling with nodetime');
});
}
console.log('Loading profiling tool: webkit-devtools-agent');
lazyRequire('webkit-devtools-agent', {
cwd: corePath
}, function(err) {
if (err) {
return;
}
return console.log("Profiling with webkit-devtools-agent on process id:", process.pid);
});
}
_ = 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');
safeps = require('safeps');
util = require('util');
superAgent = require('superagent');
extractOptsAndCallback = require('extract-opts').extractOptsAndCallback;
EventEmitterEnhanced = balUtil.EventEmitterEnhanced;
_ref = require('./base'), queryEngine = _ref.queryEngine, Backbone = _ref.Backbone, Events = _ref.Events, Model = _ref.Model, Collection = _ref.Collection, View = _ref.View, QueryCollection = _ref.QueryCollection;
FileModel = require('./models/file');
DocumentModel = require('./models/document');
FilesCollection = require('./collections/files');
ElementsCollection = require('./collections/elements');
MetaCollection = require('./collections/meta');
ScriptsCollection = require('./collections/scripts');
StylesCollection = require('./collections/styles');
PluginLoader = require('./plugin-loader');
BasePlugin = require('./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.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.eachBlock = function(fn) {
eachr(this.blocks, fn);
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.eachCollection = function(fn) {
eachr(this.collections, fn);
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;
if (opts == null) {
opts = {};
}
if (opts.collection == null) {
opts.collection = this.getDatabase();
}
file = opts.collection.get(this.filesByUrl[url]);
return file;
};
DocPad.prototype.getFileById = function(id, opts) {
var file;
if (opts == null) {
opts = {};
}
if (opts.collection == null) {
opts.collection = this.getDatabase();
}
file = opts.collection.get(id);
return file;
};
DocPad.prototype.getUrlPathname = function(url) {
return url.replace(/\?.*/, '');
};
DocPad.prototype.getFileByRoute = function(url, next) {
var cleanUrl, database, docpad, file;
docpad = this;
if (docpad.generateEnded === null) {
docpad.once('generateAfter', function() {
return docpad.getFileByRoute(url, next);
});
return this;
}
database = docpad.getDatabaseCache();
cleanUrl = docpad.getUrlPathname(url);
file = docpad.getFileByUrl(url, {
collection: database
}) || docpad.getFileByUrl(cleanUrl, {
collection: database
});
next(null, file);
return this;
};
DocPad.prototype.getFileBySelector = function(selector, opts) {
var file;
if (opts == null) {
opts = {};
}
if (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;
if (err) {
return next(err);
}
index = 0;
if (exchange) {
_ref1 = exchange.skeletons;
for (skeletonKey in _ref1) {
if (!__hasProp.call(_ref1, skeletonKey)) continue;
skeleton = _ref1[skeletonKey];
if (skeleton.id == null) {
skeleton.id = skeletonKey;
}
if (skeleton.name == null) {
skeleton.name = skeletonKey;
}
if (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: index
}));
return next(null, docpad.skeletonsCollection);
});
return this;
};
DocPad.prototype.slowPlugins = null;
DocPad.prototype.loadedPlugins = null;
DocPad.prototype.exchange = null;
DocPad.prototype.corePath = corePath;
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;
userTemplateData || (userTemplateData = {});
docpad = this;
renderPasses = this.config.renderPasses;
locale = this.getLocale();
if (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;
},
getFileById: function(id) {
var result;
this.referencesOthers();
result = docpad.getFileById(id);
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, safeps.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 = safeps.getLanguageCode(this.getLocaleCode());
this.languageCode = languageCode.toLowerCase();
}
return this.languageCode;
};
DocPad.prototype.getCountryCode = function() {
var countryCode;
if ((this.countryCode != null) === false) {
countryCode = safeps.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,
slowFilesDelay: 20 * 1000,
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',
detectEncoding: false,
renderSingleExtensions: false,
renderPasses: 1,
offline: false,
checkVersion: false,
welcome: false,
prompts: false,
poweredByDocPad: true,
helperUrl: true ? 'http://docpad-helper.herokuapp.com/' : 'http://localhost:8000/',
safeMode: false,
templateData: {},
collections: {},
events: {},
regenerateEvery: false,
localeCode: null,
env: null,
environments: {
development: {
maxAge: false,
checkVersion: /docpad$/.test(process.argv[1] || ''),
welcome: /docpad$/.test(process.argv[1] || ''),
prompts: /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.serverMiddlewareHeader = __bind(this.serverMiddlewareHeader, this);
this.serveDocument = __bind(this.serveDocument, this);
this.init = __bind(this.init, this);
this.skeleton = __bind(this.skeleton, this);
this.clean = __bind(this.clean, this);
this.update = __bind(this.update, this);
this.install = __bind(this.install, 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.load = __bind(this.load, this);
this.setConfig = __bind(this.setConfig, this);
this.ready = __bind(this.ready, this);
var action, configEventContext, docpad, logger, loggerConsole, loggers, _ref1,
_this = this;
_ref1 = 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, _ref2;
if (err && docpad.getDebugging()) {
locale = docpad.getLocale();
return docpad.log('warn', locale.reportError + ' ' + locale.errorFollows, ((_ref2 = err.stack) != null ? _ref2 : err.message).toString());
}
});
this.trackRunnerInstance = new TaskGroup().run().on('complete', function(err) {
var locale, _ref2;
if (err && docpad.getDebugging()) {
locale = docpad.getLocale();
return docpad.log('warn', locale.trackError + ' ' + locale.errorFollows, ((_ref2 = err.stack) != null ? _ref2 : err.message).toString());
}
});
if ((loggers = instanceConfig.loggers)) {
delete instanceConfig.loggers;
} else {
logger = new (require('caterpillar').Logger)();
(loggerConsole = logger.pipe(new (require('caterpillar-filter').Filter)).pipe(new (require('caterpillar-human').Human))).pipe(process.stdout);
loggers = {
logger: logger,
console: loggerConsole
};
}
safefs.unlink(this.debugLogPath, function() {});
this.setLoggers(loggers);
this.setLogLevel(this.initialConfig.logLevel);
this.on('log', function() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return docpad.log.apply(this, args);
});
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;
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 = (_base = _this.filesByOutPath)[outPath] != null ? (_base = _this.filesByOutPath)[outPath] : _base[outPath] = model.id;
if (existingModelId !== model.id) {
existingModel = _this.database.get(existingModelId);
if (existingModel) {
modelPath = model.get('fullPath') || (model.get('relativePath') + ':' + model.id);
existingModelPath = existingModel.get('fullPath') || (existingModel.get('relativePath') + ':' + existingModel.id);
message = util.format(docpad.getLocale().outPathConflict, outPath, modelPath, existingModelPath);
return docpad.warn(message);
} else {
return _this.filesByOutPath[outPath] = model.id;
}
}
});
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.destroy = function() {
this.getServer(true).serverHttp.close();
return 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, pluginName, pluginsList, tasks, _ref1,
_this = this;
_ref1 = extractOptsAndCallback(instanceConfig, next), instanceConfig = _ref1[0], next = _ref1[1];
docpad = this;
config = this.getConfig();
locale = this.getLocale();
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(', ');
}
docpad.log('info', util.format(locale.welcome, "v" + (this.getVersion())));
docpad.log('info', util.format(locale.welcomePlugins, pluginsList));
docpad.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 docpad.emitSerial('welcome', {
docpad: docpad
}, complete);
});
tasks.addTask(function(complete) {
var _this = this;
if (docpad.userConfig.username) {
return complete();
}
return require('getmac').getMac(function(err, macAddress) {
var macAddressHash, _base, _base1;
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 ((_base = docpad.userConfig).name == null) {
_base.name = "MAC " + macAddressHash;
}
if ((_base1 = docpad.userConfig).username == null) {
_base1.username = macAddressHash;
}
}
return complete();
});
});
tasks.addTask(function(complete) {
return _this.identify(complete);
});
tasks.addTask(function(complete) {
return _this.emitSerial('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, locale, postTasks, type, typePath, typePaths, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref1, _ref2, _ref3,
_this = this;
_ref1 = extractOptsAndCallback(instanceConfig, next), instanceConfig = _ref1[0], next = _ref1[1];
docpad = this;
locale = this.getLocale();
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 lazyRequire('iconv', {
cwd: corePath
}, function(err) {
if (err) {
docpad.warn(locale.encodingLoadFailed);
}
return complete();
});
});
postTasks.addTask(function(complete) {
return docpad.loadPlugins(complete);
});
postTasks.addTask(function(complete) {
return _this.extendCollections(complete);
});
postTasks.addTask(function(complete) {
return _this.emitSerial('extendTemplateData', {
templateData: _this.pluginsTemplateData
}, complete);
});
postTasks.addTask(function(complete) {
return _this.emitSerial('docpadLoaded', {}, complete);
});
postTasks.run();
return this;
};
DocPad.prototype.load = function(instanceConfig, next) {
var docpad, locale, preTasks, _ref1,
_this = this;
_ref1 = 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 safeps.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) {
var configPath;
configPath = _this.userConfigPath;
docpad.log('debug', util.format(locale.loadingUserConfig, configPath));
return _this.loadConfigPath({
configPath: configPath
}, function(err, data) {
if (err) {
return complete(err);
}
extendr.extend(_this.userConfig, data || {});
docpad.log('debug', util.format(locale.loadingUserConfig, configPath));
return complete();
});
});
preTasks.addTask(function(complete) {
var configPath;
configPath = _this.packagePath;
docpad.log('debug', util.format(locale.loadingDocPadPackageConfig, configPath));
return _this.loadConfigPath({
configPath: configPath
}, function(err, data) {
if (err) {
return complete(err);
}
data || (data = {});
_this.version = data.version;
docpad.log('debug', util.format(locale.loadingDocPadPackageConfig, configPath));
return complete();
});
});
preTasks.addTask(function(complete) {
var configPath, rootPath;
rootPath = pathUtil.resolve(_this.instanceConfig.rootPath || _this.initialConfig.rootPath);
configPath = pathUtil.resolve(rootPath, _this.instanceConfig.packagePath || _this.initialConfig.packagePath);
docpad.log('debug', util.format(locale.loadingWebsitePackageConfig, configPath));
return _this.loadConfigPath({
configPath: configPath
}, function(err, data) {
if (err) {
return complete(err);
}
data || (data = {});
_this.websitePackageConfig = data;
docpad.log('debug', util.format(locale.loadedWebsitePackageConfig, configPath));
return complete();
});
});
preTasks.addTask(function(complete) {
var configPath, rootPath;
rootPath = pathUtil.resolve(_this.instanceConfig.rootPath || _this.websitePackageConfig.rootPath || _this.initialConfig.rootPath);
configPath = pathUtil.join(rootPath, '.env');
docpad.log('debug', util.format(locale.loadingEnvConfig, configPath));
return safefs.exists(configPath, function(exists) {
if (!exists) {
return complete();
}
return require('envfile').parseFile(configPath, function(err, data) {
var key, value;
if (err) {
return complete(err);
}
for (key in data) {
if (!__hasProp.call(data, key)) continue;
value = data[key];
process.env[key] = value;
}
docpad.log('debug', util.format(locale.loadingEnvConfig, configPath));
return complete();
});
});
});
preTasks.addTask(function(complete) {
var configPath, configPaths, index, rootPath, _i, _len;
docpad.log('debug', util.format(locale.loadingWebsiteConfig));
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.loadConfigPath({
configPaths: configPaths
}, function(err, data) {
if (err) {
return complete(err);
}
data || (data = {});
extendr.extend(_this.websiteConfig, data);
docpad.log('debug', util.format(locale.loadedWebsiteConfig));
return complete();
});
});
preTasks.run();
return this;
};
DocPad.prototype.updateUserConfig = function(data, next) {
var docpad, userConfigPath, _ref1;
if (data == null) {
data = {};
}
_ref1 = 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 docpad, locale;
docpad = this;
locale = this.getLocale();
docpad.log('debug', util.format(locale.loadingConfigUrl, configUrl));
superAgent.get(configUrl).timeout(30 * 1000).end(function(err, res) {
if (err) {
return next(err);
}
return CSON.parse(res.text, next);
});
return this;
};
DocPad.prototype.loadConfigPath = function(opts, next) {
var docpad, load, locale, _ref1;
_ref1 = extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
docpad = this;
locale = this.getLocale();
load = function(configPath) {
if (!configPath) {
return next();
}
docpad.log('debug', util.format(locale.loadingConfigPath, configPath));
return safefs.exists(configPath, function(exists) {
if (!exists) {
return next();
}
return CSON.parseFile(configPath, next);
});
};
if (opts.configPath) {
load(opts.configPath);
} else {
this.getConfigPath(opts, function(err, configPath) {
return load(configPath);
});
}
return this;
};
DocPad.prototype.getConfigPath = function(opts, next) {
var config, docpad, result, tasks, _ref1;
_ref1 = extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
docpad = this;
config = this.getConfig();
result = null;
if (opts.configPaths == null) {
opts.configPaths = config.configPaths;
}
if (!typeChecker.isArray(opts.configPaths)) {
opts.configPaths = [opts.configPaths];
}
tasks = new TaskGroup().once('complete', function(err) {
return next(err, result);
});
opts.configPaths.forEach(function(configPath) {
return tasks.addTask(function(complete) {
if (result) {
return complete();
}
return safefs.exists(configPath, function(exists) {
if (exists) {
result = configPath;
return tasks.exit();
} 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.relativePath));
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.relativePath));
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.relativePath));
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.relativePath));
}),
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.relativePath));
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.emitSerial('extendCollections', {}, next);
});
eachr(this.config.collections || {}, function(fn, name) {
return tasks.addTask(function(complete) {
return ambi([fn.bind(docpad), fn], database, function(err, collection) {
if (err) {
docpad.error(err);
return complete();
} else if (!(collection instanceof QueryCollection)) {
docpad.log('warn', util.format(locale.errorInvalidCollection, name));
return complete();
}
if (collection) {
collection.live(true);
}
docpad.setCollection(name, collection);
return complete();
});
});
});
tasks.run();
return this;
};
DocPad.prototype.resetCollections = function(next) {
var database, docpad, meta;
docpad = this;
database = this.getDatabase();
this.databaseCache = new FilesCollection(database.models);
database.reset([]);
meta = this.getBlock('meta').reset([]);
if (docpad.getConfig().poweredByDocPad !== false) {
meta.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.emitSerial('populateCollections', {}, next);
return this;
};
DocPad.prototype.initGitRepo = function(opts, next) {
var config, docpad, _ref1;
_ref1 = extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
docpad = this;
config = this.getConfig();
if (opts.cwd == null) {
opts.cwd = config.rootPath;
}
if (opts.output == null) {
opts.output = this.getDebugging();
}
safeps.initGitRepo(opts, next);
return this;
};
DocPad.prototype.initNodeModules = function(opts, next) {
var config, docpad, _ref1;
_ref1 = extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
docpad = this;
config = this.getConfig();
if (opts.cwd == null) {
opts.cwd = config.rootPath;
}
if (opts.output == null) {
opts.output = docpad.getDebugging();
}
if (opts.force == null) {
opts.force = true;
}
if (opts.args == null) {
opts.args = [];
}
if (config.force) {
opts.args.push('--force');
}
if (config.offline) {
opts.args.push('--no-registry');
}
if (opts.output) {
docpad.log('info', 'npm install');
}
safeps.initNodeModules(opts, next);
return this;
};
DocPad.prototype.initNodeModule = function(names, opts) {
var command, config, docpad, next, _ref1;
_ref1 = extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
docpad = this;
config = this.getConfig();
if (opts.cwd == null) {
opts.cwd = config.rootPath;
}
if (opts.output == null) {
opts.output = docpad.getDebugging();
}
if (opts.args == null) {
opts.args = [];
}
if (opts.save == null) {
opts.save = true;
}
if (opts.save === true) {
opts.save = '--save';
}
command = ['npm', 'install'];
if (!typeChecker.isArray(names)) {
names = names.split(/\s/);
}
names.forEach(function(name) {
if (name.indexOf('@') === -1) {
name += '@latest';
}
return command.push(name);
});
command.push.apply(command, opts.args);
if (config.force) {
command.push('--force');
}
if (config.offline) {
command.push('--no-registry');
}
if (opts.save) {
command.push(opts.save);
}
if (opts.output) {
docpad.log('info', command.join(' '));
}
safeps.spawn(command, opts, next);
return this;
};
DocPad.prototype.setLogLevel = function(level) {
var loggers;
this.getLogger().setConfig({
level: level
});
if (level === 7) {
loggers = this.getLoggers();
if (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.getConfig().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 config, data, docpad, locale, message, _ref1;
if (type == null) {
type = 'err';
}
docpad = this;
config = this.getConfig();
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;
message = ((_ref1 = err.stack) != null ? _ref1 : err.message).toString();
docpad.log(type, locale.errorOccured, '\n' + message);
docpad.notify(err.message, {
title: locale.errorOccured
});
if (config.offline === false && config.reportErrors) {
data = {};
data.message = err.message;
if (err.stack) {
data.stack = err.stack.toString();
}
data.config = config;
data.env = process.env;
docpad.track('error', data, 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.checkRequest = function(next) {
return function(err, res) {
var _ref1, _ref2;
if (err) {
return next(err, res);
}
if (((_ref1 = res.body) != null ? _ref1.success : void 0) === false || ((_ref2 = res.body) != null ? _ref2.error : void 0)) {
err = new Error(res.body.error || 'unknown request error');
return next(err, res);
}
return next(null, res);
};
};
DocPad.prototype.subscribe = function(next) {
var data, helperUrl;
helperUrl = this.getConfig().helperUrl;
data = {};
data.name = this.userConfig.name;
data.email = this.userConfig.email;
data.username = this.userConfig.username;
superAgent.post(helperUrl).type('json').set('Accept', 'application/json').query({
method: 'add-subscriber'
}).send(data).timeout(30 * 1000).end(this.checkRequest(next));
return this;
};
DocPad.prototype.track = function(name, things, next) {
var config, data, docpad, _ref1, _ref2;
if (things == null) {
things = {};
}
docpad = this;
config = this.getConfig();
if (config.offline === false && config.reportStatistics && ((_ref1 = this.userConfig) != null ? _ref1.username : void 0)) {
data = {};
data.userId = this.userConfig.username;
data.event = name;
data.properties = things;
if ((_ref2 = this.websitePackageConfig) != null ? _ref2.name : void 0) {
things.websiteName = this.websitePackageConfig.name;
}
things.platform = this.getProcessPlatform();
things.environment = this.getEnvironment();
things.version = this.getVersion();
things.nodeVersion = this.getProcessVersion();
eachr(docpad.loadedPlugins, function(value, key) {
return things['plugin-' + key] = value.version || true;
});
docpad.getTrackRunner().addTask(function(complete) {
return superAgent.post(config.helperUrl).type('json').set('Accept', 'application/json').query({
method: 'analytics',
action: 'track'
}).send(data).timeout(30 * 1000).end(docpad.checkRequest(complete));
});
}
if (typeof next === "function") {
next();
}
return this;
};
DocPad.prototype.identify = function(next) {
var config, data, docpad, now, things, _ref1,
_this = this;
docpad = this;
config = this.getConfig();
if (config.offline === false && config.reportStatistics && ((_ref1 = this.userConfig) != null ? _ref1.username : void 0)) {
data = {};
data.userId = this.userConfig.username;
data.traits = things = {};
now = new Date();
things.username = this.userConfig.username;
things.email = this.userConfig.email;
things.name = this.userConfig.name;
things.lastLogin = now.toISOString();
things.lastSeen = now.toISOString();
things.countryCode = safeps.getCountryCode();
things.languageCode = safeps.getLanguageCode();
things.platform = this.getProcessPlatform();
things.version = this.getVersion();
things.nodeVersion = this.getProcessVersion();
if (docpad.userConfig.identified !== true) {
things.created = now.toISOString();
docpad.getTrackRunner().addTask(function(complete) {
var _this = this;
return superAgent.post(config.helperUrl).type('json').set('Accept', 'application/json').query({
method: 'analytics',
action: 'identify'
}).send(data).timeout(30 * 1000).end(docpad.checkRequest(function(err) {
docpad.updateUserConfig({
identified: true
});
return complete(err);
}));
});
} else {
docpad.getTrackRunner().addTask(function(complete) {
return superAgent.post(config.helperUrl).type('json').set('Accept', 'application/json').query({
method: 'analytics',
action: 'identify'
}).send(data).timeout(30 * 1000).end(docpad.checkRequest(complete));
});
}
}
if (typeof next === "function") {
next();
}
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.emitSerial.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.emitSerial.apply(docpad, ['render'].concat(__slice.call(args)));
});
document.on('renderDocument', function() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return docpad.emitSerial.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) {
if (opts == null) {
opts = {};
}
if (opts.createFunction == null) {
opts.createFunction = this.createFile;
}
return this.parseDirectory(opts, next);
};
DocPad.prototype.parseDocumentDirectory = function(opts, next) {
if (opts == null) {
opts = {};
}
if (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();
safefs.exists(path, function(exists) {
if (!exists) {
docpad.log('debug', util.format(locale.renderDirectoryNonexistant, path));
return next();
}
docpad.log('debug', util.format(locale.renderDirectoryParsing, path));
return docpad.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;
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) {
return tasks.addTask(function(complete) {
return safefs.exists(pluginsPath, function(exists) {
if (!exists) {
return complete();
}
return docpad.loadPluginsIn(pluginsPath, complete);
});
});
});
(this.config.pluginPaths || []).forEach(function(pluginPath) {
return tasks.addTask(function(complete) {
return safefs.exists(pluginPath, function(exists) {
if (!exists) {
return complete();
}
return docpad.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) {
var message;
if (err) {
message = util.format(locale.pluginFailedToLoad, pluginName, fileFullPath) + ' ' + locale.errorFollows;
docpad.warn(message, 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 config, docpad, locale;
docpad = this;
config = this.getConfig();
if (config.offline || !config.checkVersion) {
return this;
}
docpad = this;
locale = this.getLocale();
balUtil.packageCompare({
local: this.packagePath,
remote: 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 config, docpad, exchangeUrl, locale;
docpad = this;
config = this.getConfig();
locale = this.getLocale();
if (typeChecker.isEmptyObject(docpad.exchange) === false) {
return next(null, docpad.exchange);
}
if (config.offline) {
return next(null, null);
}
docpad.log('info', locale.exchangeUpdate + ' ' + locale.pleaseWait);
exchangeUrl = config.exchangeUrl + '?version=' + this.version;
docpad.loadConfigUrl(exchangeUrl, function(err, parsedData) {
if (err) {
locale = docpad.getLocale();
docpad.log('notice', locale.exchangeError + ' ' + locale.errorFollows, err);
return next();
}
docpad.log('info', locale.exchangeUpdated);
docpad.exchange = parsedData;
return next(null, parsedData);
});
return this;
};
DocPad.prototype.loadFiles = function(opts, next) {
var collection, config, database, docpad, locale, slowFilesObject, slowFilesTimer;
if (opts == null) {
opts = {};
}
docpad = this;
config = this.getConfig();
locale = this.getLocale();
database = this.getDatabase();
collection = opts.collection;
slowFilesObject = {};
slowFilesTimer = null;
docpad.log('debug', util.format(locale.loadingFiles, collection.length));
docpad.emitSerial('loadBefore', {
collection: collection
}, function(err) {
var tasks, _ref1;
if (err) {
return next(err);
}
tasks = new TaskGroup().setConfig({
concurrency: 0
}).once('complete', function(err) {
clearInterval(slowFilesTimer);
slowFilesTimer = null;
if (err) {
return next(err);
}
return docpad.emitSerial('loadAfter', {
collection: collection
}, function(err) {
docpad.log('debug', util.format(locale.loadedFiles, collection.length));
return next();
});
});
if ((_ref1 = opts.progress) != null) {
_ref1.step('loadFiles').total(collection.length);
}
collection.forEach(function(file) {
slowFilesObject[file.id] = file.get('relativePath') || file.id;
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, _ref2;
delete slowFilesObject[file.id];
if ((_ref2 = opts.progress) != null) {
_ref2.tick();
}
if (err) {
docpad.warn(util.format(locale.loadingFileFailed, fileRelativePath) + ' ' + 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();
});
});
});
slowFilesTimer = setInterval(function() {
var key, slowFilesArray, value;
slowFilesArray = (function() {
var _results;
_results = [];
for (key in slowFilesObject) {
if (!__hasProp.call(slowFilesObject, key)) continue;
value = slowFilesObject[key];
_results.push(value || key);
}
return _results;
})();
return docpad.log('info', util.format(locale.slowFiles, 'loadFiles') + ' \n' + slowFilesArray.join('\n'));
}, config.slowFilesDelay);
return tasks.run();
});
return this;
};
DocPad.prototype.contextualizeFiles = function(opts, next) {
var collection, config, docpad, locale, slowFilesObject, slowFilesTimer, templateData;
if (opts == null) {
opts = {};
}
docpad = this;
config = this.getConfig();
locale = this.getLocale();
collection = opts.collection, templateData = opts.templateData;
slowFilesObject = {};
slowFilesTimer = null;
docpad.log('debug', util.format(locale.contextualizingFiles, collection.length));
docpad.emitSerial('contextualizeBefore', {
collection: collection,
templateData: templateData
}, function(err) {
var tasks, _ref1;
if (err) {
return next(err);
}
tasks = new TaskGroup().setConfig({
concurrency: 0
}).once('complete', function(err) {
clearInterval(slowFilesTimer);
slowFilesTimer = null;
if (err) {
return next(err);
}
return docpad.emitSerial('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) {
slowFilesObject[file.id] = file.get('relativePath') || file.id;
return tasks.addTask(function(complete) {
return file.contextualize(function(err) {
var _ref2;
delete slowFilesObject[file.id];
if ((_ref2 = opts.progress) != null) {
_ref2.tick();
}
return complete(err);
});
});
});
slowFilesTimer = setInterval(function() {
var key, slowFilesArray, value;
slowFilesArray = (function() {
var _results;
_results = [];
for (key in slowFilesObject) {
if (!__hasProp.call(slowFilesObject, key)) continue;
value = slowFilesObject[key];
_results.push(value || key);
}
return _results;
})();
return docpad.log('info', util.format(locale.slowFiles, 'contextualizeFiles') + ' \n' + slowFilesArray.join('\n'));
}, config.slowFilesDelay);
return tasks.run();
});
return this;
};
DocPad.prototype.renderFiles = function(opts, next) {
var collection, config, docpad, locale, renderCollection, renderFile, renderPasses, slowFilesObject, slowFilesTimer, templateData,
_this = this;
if (opts == null) {
opts = {};
}
docpad = this;
config = this.getConfig();
locale = this.getLocale();
collection = opts.collection, templateData = opts.templateData, renderPasses = opts.renderPasses;
slowFilesObject = {};
slowFilesTimer = null;
docpad.log('debug', util.format(locale.renderingFiles, collection.length));
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) {
slowFilesObject[file.id] = file.get('relativePath');
return subTasks.addTask(function(complete) {
return renderFile(file, function(err) {
var _ref2;
delete slowFilesObject[file.id] || file.id;
if ((_ref2 = opts.progress) != null) {
_ref2.tick();
}
return complete(err);
});
});
});
subTasks.run();
return collectionToRender;
};
docpad.emitSerial('renderBefore', {
collection: collection,
templateData: templateData
}, function(err) {
var initialCollection, subsequentCollection, tasks, _i, _results;
if (err) {
return next(err);
}
tasks = new TaskGroup().once('complete', function(err) {
clearInterval(slowFilesTimer);
slowFilesTimer = null;
if (err) {
return next(err);
}
return docpad.emitSerial('renderAfter', {
collection: collection
}, function(err) {
if (err) {
return next(err);
}
docpad.log('debug', util.format(locale.renderedFiles, collection.length));
return next();
});
});
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);
});
});
}
slowFilesTimer = setInterval(function() {
var key, slowFilesArray, value;
slowFilesArray = (function() {
var _results1;
_results1 = [];
for (key in slowFilesObject) {
if (!__hasProp.call(slowFilesObject, key)) continue;
value = slowFilesObject[key];
_results1.push(value || key);
}
return _results1;
})();
return docpad.log('info', util.format(locale.slowFiles, 'renderFiles') + ' \n' + slowFilesArray.join('\n'));
}, config.slowFilesDelay);
return tasks.run();
});
return this;
};
DocPad.prototype.writeFiles = function(opts, next) {
var collection, config, docpad, locale, slowFilesObject, slowFilesTimer, templateData,
_this = this;
if (opts == null) {
opts = {};
}
docpad = this;
config = this.getConfig();
locale = this.getLocale();
collection = opts.collection, templateData = opts.templateData;
slowFilesObject = {};
slowFilesTimer = null;
docpad.log('debug', util.format(locale.writingFiles, collection.length));
docpad.emitSerial('writeBefore', {
collection: collection,
templateData: templateData
}, function(err) {
var tasks, _ref1;
if (err) {
return next(err);
}
tasks = new TaskGroup().setConfig({
concurrency: 0
}).once('complete', function(err) {
clearInterval(slowFilesTimer);
slowFilesTimer = null;
if (err) {
return next(err);
}
return docpad.emitSerial('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) {
slowFilesObject[file.id] = file.get('relativePath');
return tasks.addTask(function(complete) {
var dynamic, finish, relativePath, write;
dynamic = file.get('dynamic');
write = file.get('write');
relativePath = file.get('relativePath');
finish = function(err) {
var _ref2;
delete slowFilesObject[file.id] || file.id;
if ((_ref2 = opts.progress) != null) {
_ref2.tick();
}
return complete(err);
};
if (dynamic || ((write != null) && !write) || !relativePath) {
finish();
} else if (file.writeRendered != null) {
file.writeRendered(finish);
} else if (file.write != null) {
file.write(finish);
} else {
err = new Error(locale.unknownModelInCollection);
finish(err);
}
return true;
});
});
slowFilesTimer = setInterval(function() {
var key, slowFilesArray, value;
slowFilesArray = (function() {
var _results;
_results = [];
for (key in slowFilesObject) {
if (!__hasProp.call(slowFilesObject, key)) continue;
value = slowFilesObject[key];
_results.push(value || key);
}
return _results;
})();
return docpad.log('info', util.format(locale.slowFiles, 'writeFiles') + ' \n' + slowFilesArray.join('\n'));
}, config.slowFilesDelay);
return tasks.run();
});
return this;
};
DocPad.prototype.action = function(action, opts, next) {
var actions, docpad, forward, locale, runner, tasks, _ref1;
_ref1 = 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;
}
docpad.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) : [];
docpad.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 = 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('notice', locale.renderNoPlugins);
}
tasks.addTask(function(complete) {
return safefs.exists(config.srcPath, function(exists) {
var err;
if (!exists) {
err = new Error(locale.renderNonexistant);
return complete(err);
}
return complete();
});
});
tasks.addTask(function(complete) {
return docpad.resetCollections(complete);
});
}
tasks.addTask(function(complete) {
return docpad.emitSerial('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 = extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
docpad = this;
database = this.getDatabase();
config = this.getConfig();
locale = this.getLocale();
this.emitSerial('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.emitSerial('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 = 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 = 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.emitSerial('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.progress = null;
DocPad.prototype.createProgress = function() {
var config, docpad, progress;
docpad = this;
config = docpad.getConfig();
progress = null;
if (config.prompts && this.getLogLevel() === 6) {
progress = require('progressbar').create();
this.getLoggers().console.unpipe(process.stdout);
this.getLogger().once('log', progress.logListener != null ? progress.logListener : progress.logListener = function(data) {
if (data.levelNumber <= 5) {
return docpad.destroyProgress(progress);
}
});
}
return progress;
};
DocPad.prototype.destroyProgress = function(progress) {
if (progress) {
progress.finish();
this.getLoggers().console.unpipe(process.stdout).pipe(process.stdout);
}
return progress;
};
DocPad.prototype.generate = function(opts, next) {
var config, docpad, finish, locale, _ref1, _ref2;
_ref1 = extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
docpad = this;
config = this.getConfig();
locale = this.getLocale();
if (opts.reset == null) {
opts.reset = true;
}
if (((_ref2 = opts.collection) != null ? _ref2.length : void 0) === 0) {
return next();
}
if (opts.progress == null) {
opts.progress = this.createProgress();
}
finish = function(err) {
if (opts.progress) {
docpad.destroyProgress(opts.progress);
opts.progress = null;
}
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 = 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 = 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 = 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 = 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 = 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 = 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;
_ref1 = extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
if (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 = 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 = 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) {
opts || (opts = {});
if (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 = 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);
}
});
};
safefs.exists(srcPath, function(exists) {
if (exists) {
return runDocpad();
}
return 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.initInstall = function(opts, next) {
var config, docpad, tasks, _ref1;
_ref1 = extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
docpad = this;
config = this.getConfig();
tasks = new TaskGroup().setConfig({
concurrency: 0
}).once('complete', next);
tasks.addTask(function(complete) {
var path;
path = pathUtil.join(config.rootPath, 'node_modules');
return safefs.ensurePath(path, complete);
});
tasks.addTask(function(complete) {
var path;
path = pathUtil.join(config.rootPath, 'package.json');
return safefs.exists(path, function(exists) {
var data;
if (exists) {
return complete();
}
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',
scripts: {
start: 'node_modules/docpad/bin/docpad-server'
}
}, null, ' ');
return safefs.writeFile(path, data, complete);
});
});
tasks.run();
return this;
};
DocPad.prototype.install = function(opts, next) {
var config, docpad, tasks, _ref1;
_ref1 = extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
docpad = this;
config = this.getConfig();
tasks = new TaskGroup().once('complete', next);
tasks.addTask(function(complete) {
return docpad.initInstall(opts, complete);
});
if (opts.plugin) {
tasks.addTask(function(complete) {
if (/^docpad-plugin-/.test(opts.plugin) === false) {
opts.plugin = "docpad-plugin-" + opts.plugin;
}
if (opts.plugin.indexOf('@') === -1) {
opts.plugin += '@2';
}
return docpad.initNodeModule(opts.plugin, {
output: true,
next: complete
});
});
}
tasks.addTask(function(complete) {
return docpad.initNodeModules({
output: true,
next: complete
});
});
tasks.addTask(function(complete) {
return docpad.load(complete);
});
tasks.run();
return this;
};
DocPad.prototype.update = function(opts, next) {
var config, dependencies, devDependencies, docpad, tasks, _ref1;
_ref1 = extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
docpad = this;
config = this.getConfig();
tasks = new TaskGroup().once('complete', next);
tasks.addTask(function(complete) {
return docpad.initInstall(opts, complete);
});
tasks.addTask(function(complete) {
return docpad.initNodeModule('docpad@6', {
output: true,
next: complete
});
});
dependencies = [];
eachr(docpad.websitePackageConfig.dependencies, function(version, name) {
if (/^docpad-plugin-/.test(name) === false) {
return;
}
return dependencies.push(name + '@2');
});
tasks.addTask(function(complete) {
return docpad.initNodeModule(dependencies, {
output: true,
next: complete
});
});
devDependencies = [];
eachr(docpad.websitePackageConfig.devDependencies, function(version, name) {
if (/^docpad-plugin-/.test(name) === false) {
return;
}
return devDependencies.push(name + '@2');
});
tasks.addTask(function(complete) {
return docpad.initNodeModule(devDependencies, {
save: '--save-dev',
output: true,
next: complete
});
});
tasks.addTask(function(complete) {
return docpad.initNodeModules({
output: true,
next: complete
});
});
tasks.run();
return this;
};
DocPad.prototype.clean = function(opts, next) {
var docpad, locale, outPath, rootPath, _ref1, _ref2;
_ref1 = 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.initSkeleton = function(skeletonModel, opts, next) {
var config, docpad, tasks, _ref1;
_ref1 = extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
docpad = this;
config = this.getConfig();
if (opts.destinationPath == null) {
opts.destinationPath = config.rootPath;
}
tasks = new TaskGroup().once('complete', next);
tasks.addTask(function(complete) {
return safefs.ensurePath(opts.destinationPath, complete);
});
if ((skeletonModel != null) && skeletonModel.id !== 'none') {
tasks.addTask(function(complete) {
return docpad.initGitRepo({
path: opts.destinationPath,
url: skeletonModel.get('repo'),
branch: skeletonModel.get('branch'),
remote: 'skeleton',
output: true,
next: complete
});
});
} else {
tasks.addTask(function(complete) {
return safefs.ensurePath(config.srcPath, complete);
});
tasks.addGroup(function() {
this.setConfig({
concurrency: 0
});
this.addTask(function(complete) {
var path;
path = pathUtil.join(config.rootPath, 'README.md');
return safefs.exists(path, function(exists) {
var data;
if (exists) {
return complete();
}
data = "# Your [DocPad](http://docpad.org) Project\n\n## License\nCopyright &copy; " + ((new Date()).getFullYear()) + "+ All rights reserved.";
return safefs.writeFile(path, data, complete);
});
});
this.addTask(function(complete) {
return docpad.getConfigPath(function(err, path) {
var data;
if (err || path) {
return complete(err);
}
path = pathUtil.join(config.rootPath, 'docpad.coffee');
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(path, data, complete);
});
});
this.addTask(function(complete) {
return safefs.ensurePath(config.documentsPaths[0], complete);
});
this.addTask(function(complete) {
return safefs.ensurePath(config.layoutsPaths[0], complete);
});
return this.addTask(function(complete) {
return safefs.ensurePath(config.filesPaths[0], complete);
});
});
}
tasks.run();
return this;
};
DocPad.prototype.installSkeleton = function(skeletonModel, opts, next) {
var docpad, _ref1;
_ref1 = extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
docpad = this;
if (opts.destinationPath == null) {
opts.destinationPath = this.getConfig().rootPath;
}
docpad.initSkeleton(skeletonModel, opts, function(err) {
if (err) {
return next(err);
}
return docpad.install(next);
});
return this;
};
DocPad.prototype.useSkeleton = function(skeletonModel, opts, next) {
var docpad, locale, skeletonId, skeletonName, _ref1;
_ref1 = extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
docpad = this;
locale = this.getLocale();
if (opts.destinationPath == null) {
opts.destinationPath = this.getConfig().rootPath;
}
skeletonId = (skeletonModel != null ? skeletonModel.id : void 0) || 'none';
skeletonName = (skeletonModel != null ? skeletonModel.get('name') : void 0) || locale.skeletonNoneName;
docpad.track('skeleton-use', {
skeletonId: skeletonId
});
docpad.log('info', util.format(locale.skeletonInstall, skeletonName, opts.destinationPath) + ' ' + locale.pleaseWait);
docpad.installSkeleton(skeletonModel, opts, function(err) {
if (err) {
return next(err);
}
docpad.log('info', locale.skeletonInstalled);
return next(err);
});
return this;
};
DocPad.prototype.selectSkeleton = function(opts, next) {
var docpad, _ref1;
_ref1 = extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
docpad = this;
if (opts.selectSkeletonCallback == null) {
opts.selectSkeletonCallback = null;
}
docpad.track('skeleton-ask');
docpad.getSkeletons(function(err, skeletonsCollection) {
if (err) {
return next(err);
}
return opts.selectSkeletonCallback(skeletonsCollection, next);
});
return this;
};
DocPad.prototype.skeleton = function(opts, next) {
var config, docpad, _ref1;
_ref1 = extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
docpad = this;
config = this.getConfig();
if (opts.selectSkeletonCallback == null) {
opts.selectSkeletonCallback = null;
}
safefs.exists(config.srcPath, function(exists) {
var err;
if (exists) {
err = new Error(locale.skeletonExists);
return next(err);
}
return docpad.selectSkeleton(opts, function(err, skeletonModel) {
if (err) {
return next(err);
}
return docpad.useSkeleton(skeletonModel, next);
});
});
return this;
};
DocPad.prototype.init = function(opts, next) {
var config, docpad, locale, _ref1;
_ref1 = extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
docpad = this;
locale = this.getLocale();
config = this.getConfig();
safefs.exists(config.srcPath, function(exists) {
var err;
if (exists) {
err = new Error(locale.skeletonExists);
return next(err);
}
return docpad.useSkeleton(null, next);
});
return this;
};
DocPad.prototype.serveDocument = function(opts, next) {
var content, contentType, docpad, document, dynamic, err, req, res, templateData, _ref1;
_ref1 = 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 docpad;
docpad = this;
docpad.getFileByRoute(req.url, function(err, file) {
var cleanUrl, url;
if (err || (file != null) === false) {
return next(err);
}
url = file.get('url');
cleanUrl = docpad.getUrlPathname(url);
if ((url !== cleanUrl) && (url !== req.url)) {
return res.redirect(301, url);
}
return 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;
http = null;
express = null;
_ref1 = 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 (opts.middlewareBodyParser == null) {
opts.middlewareBodyParser = (_ref2 = config.middlewareBodyParser) != null ? _ref2 : config.middlewareStandard;
}
if (opts.middlewareMethodOverride == null) {
opts.middlewareMethodOverride = (_ref3 = config.middlewareMethodOverride) != null ? _ref3 : config.middlewareStandard;
}
if (opts.middlewareExpressRouter == null) {
opts.middlewareExpressRouter = (_ref4 = config.middlewareExpressRouter) != null ? _ref4 : config.middlewareStandard;
}
if (opts.middleware404 == null) {
opts.middleware404 = config.middleware404;
}
if (opts.middleware500 == null) {
opts.middleware500 = config.middleware500;
}
finish = function(err) {
if (err) {
return next(err);
}
return docpad.emitSerial('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.emitSerial('serverBefore', {}, function(err) {
var _ref5;
if (err) {
return finish(err);
}
_ref5 = docpad.getServer(true), serverExpress = _ref5.serverExpress, serverHttp = _ref5.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.emitSerial('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(){});
}
};