'use strict';
var fs = require('fs');
var xml = require('xml');
var _ = require('lodash');
var moment = require('moment');
var joinUrl = require('../util/joinUrl.js');
var togError = require('./togErrors');
var Handlebars = null;
var templateCollection = (function () {
var templateCollection = {};
return {
getItem: function (key) {
return templateCollection[key];
},
allKeys: function () {
return Object.keys(templateCollection);
},
addTemplate: function (key, value) {
if (this[key]) {
throw 'Key [' + key + '] already exists. Current value[' + this[key] + '] new file [' + value + ']';
}
this[key] = fs.readFileSync(value).toString();
}.bind(templateCollection)
};
})();
function renderLayout(metadata) {
var result;
var layout = metadata.layout;
if (layout) {
if (layout === 'none') {
result = Handlebars.compile(metadata.contents)(metadata);
return result;
} else {
layout = 'layouts/' + layout;
var template = Handlebars.templates[layout];
if (!template) {
throw 'unknown layout: ' + layout;
}
result = template(metadata);
return result;
}
} else {
//console.log(file.contents.toString());
//var template = Handlebars.compile(file.contents.toString());
//var result = template(metadata);
//file.contents = new Buffer(result);
console.log(metadata);
throw 'no layout specified?';
//if (!pageContext.contents) {
// console.log('file:', file);
// console.log('pageContext:', pageContext);
// throw 'contents:... not defined?';
//}
//file.contents = new Buffer(pageContext.contents);
}
}
var renderTemplate = function (templateName, context) {
if (!templateName) {
throw 'argument[0] templateName was [' + templateName + ']';
}
var template = Handlebars.templates[templateName];
if (!template && typeof template !== 'function') {
throw 'Could not get template with templateName [' + templateName + '], all known Templates on Handlebars.templates=' + JSON.stringify(Object.keys(Handlebars.templates), null, ' ');
}
var result;
// try {
//console.log('template', rawTemplate);
result = template(context);
//console.log('result:', result);
//} catch (e) {
// console.error('ERROR: ', {
// 'templateName:': templateName, 'rawTemplate:': template, 'context:': context, 'error:': e});
// //console.error('ERROR: templateName:', templateName);
// //console.error('ERROR: context:', context);
// //console.error('ERROR: ', e);
// throw e;
//}
return result;
};
var renderContentGulp = function () {
var through = require('through2');
var PLUGIN_NAME = 'tog-renderContent';
var stream = through.obj(function (file, enc, callback) {
var metadata = file.togMetadata;
//console.log(metadata.handlebarCompile)
if (metadata && metadata.handlebarCompile) {
if (file.isBuffer()) {
var contents = file.contents.toString();
// pre-compile and render the page/post
var result = Handlebars.compile(contents)(metadata);
metadata.contents = result;
file.contents = new Buffer(result);
}
if (file.isStream()) {
this.emit('error', togError.noStreamSupport(PLUGIN_NAME));
return callback();
}
}
this.push(file);
return callback();
});
// returning the file stream
return stream;
};
var renderTemplateGulp = function () {
var through = require('through2');
var PLUGIN_NAME = 'tog-renderTemplate';
var stream = through.obj(function (file, enc, callback) {
var metadata = file.togMetadata;
if (metadata) {
var contents = '';
if (file.isBuffer()) {
contents = file.contents.toString();
// pre-compile and render the page/post
metadata.contents = contents;
}
if (file.isStream()) {
this.emit('error', togError.noStreamSupport(PLUGIN_NAME));
return callback();
}
var result = renderLayout(metadata);
file.contents = new Buffer(result);
}
this.push(file);
return callback();
});
// returning the file stream
return stream;
};
module.exports = function (HandlebarsInput) {
if (!HandlebarsInput) {
throw 'must pass the Handlebars object as the first parameter.';
}
Handlebars = HandlebarsInput;
_.extend(Handlebars.helpers, require('diy-handlebars-helpers'));
Handlebars.registerHelper('include', function (name) {
//console.log('#include ' + name);
return renderTemplate(name, this);
});
Handlebars.registerHelper('length', function (array) {
if (array && array.length > 0) {
return array.length;
}
return 0;
});
Handlebars.registerHelper('cdata_escape', function (value) {
return xml([{ _cdata: value }]);
});
Handlebars.registerHelper('date_to_xmlschema', function (date) {
return moment(date).toISOString();
});
Handlebars.registerHelper('formatDate', function (date, options) {
var m = moment(this._date);
if (m.isValid()) {
if (options.hash.format) {
return m.format(options.hash.format);
} else {
return m.format('MMM Do YYYY');
}
}
throw 'unable to format [' + date + '] as a date';
});
Handlebars.registerHelper('json', function (data) {
var o = {};
o.o = o;
var cache = [];
var result = JSON.stringify(data, function (key, value) {
if (typeof value === 'object' && value !== null) {
if (cache.indexOf(value) !== -1) {
// Circular reference found, discard key
return;
}
// Store value in our collection
cache.push(value);
}
return value;
}, ' ');
cache = null; // Enable garbage collection
//console.log('JSON:', data);
//var result = JSON.stringify(data);
//console.log('JSON:', result);
return result;
});
Handlebars.registerHelper('fullUrl', function (url) {
// {% capture fullUrl %}{{ url }}{{#if permalink '.html'}}{{ url }}{{else}}{{ page.url | remove:'index.html' | strip_slash }}{{/if}}{% endcapture %}
return joinUrl(this.site.url, url);
});
Handlebars.registerHelper('iso8601', function (date) {
// {% capture fullUrl %}{{ url }}{{#if permalink '.html'}}{{ url }}{{else}}{{ page.url | remove:'index.html' | strip_slash }}{{/if}}{% endcapture %}
return moment(date).toISOString();
});
Handlebars.registerHelper('postCompare', function (rvalue) {
if (this.isPublished) {
if (this.seriesTitle === rvalue.seriesTitle) {
return '(current) - ' + this.seriesTitle;
} else {
return '<a href="' + this.url + '">' + this.seriesTitle + '</a>';
}
} else {
if (this.seriesTitle === rvalue.seriesTitle) {
return '(current) - ' + this.seriesTitle;
} else {
return '(coming soon) - ' + this.seriesTitle;
}
}
});
Handlebars.registerHelper('compare', function (lvalue, rvalue, options) {
if (arguments.length < 3) {
throw new Error('Handlerbars Helper \'compare\' needs 2 parameters');
}
var operator = options.hash.operator || '==';
var operators = {
'==': function (l, r) { return l == r; }, // jshint ignore:line
'===': function (l, r) { return l === r; },
'!=': function (l, r) { return l != r; }, // jshint ignore:line
'<': function (l, r) { return l < r; },
'>': function (l, r) { return l > r; },
'<=': function (l, r) { return l <= r; },
'>=': function (l, r) { return l >= r; },
'typeof': function (l, r) { return typeof l == r; } // jshint ignore:line
};
if (!operators[operator]) {
throw new Error('Handlerbars Helper \'compare\' doesn\'t know the operator ' + operator);
}
var result = operators[operator](lvalue, rvalue);
if (result) {
return options.fn(this);
} else {
return options.inverse(this);
}
});
return {
templateCollection: templateCollection,
renderTemplate: renderTemplate,
renderLayout: renderLayout,
renderContentGulp: renderContentGulp,
renderTemplateGulp: renderTemplateGulp,
};
};