var Q = require('q'); var fs = require('fs'); var path = require('path'); var glob = require('glob'); var stringify = require('json-to-html'); var Liquid = require('liquid-node'); var chokidar = require('chokidar'); /** * Define any custom liquid filters here. */ var filters = { /** * Return a string formatted version of a JSON object. * Useful for quick debugging of template data. */ prettify: function(obj) { try { return '
' + stringify(obj) + '
'; } catch (e) { return 'Error prettifying'; } }, /** * Serialize Javascript objects into a JSON string */ stringify: function(obj) { try { return JSON.stringify(obj); } catch (e) { return 'Error stringifying'; } }, }; /** * Manages templates. Only supports Liquid currently/ */ function OKTemplateRepo(options) { options = options || {}; var self = this; var root = this._root = options.root || 'templates'; // TODO Support more templates? var ext = this._ext = 'liquid'; var cache = this._cache = {}; var engine = this._engine = new Liquid.Engine; var debug = options.debug; var globString = this._globString = root + '/*.' + ext engine.registerFilters(filters); engine.fileSystem = new Liquid.LocalFileSystem(root, ext); this._populateCache(engine, cache, ext); if (debug) { var watcher = chokidar.watch(globString); watcher.on('change', reloadTemplate); watcher.on('add', reloadTemplate); } function reloadTemplate(path) { self._loadTemplate(path); } } OKTemplateRepo.prototype.getTemplate = function getTemplate(name) { return this._cache[name]; } OKTemplateRepo.prototype._loadTemplate = function loadTemplate(filePath) { var engine = this._engine var name = path.basename(filePath, '.' + this._ext); var templateString = fs.readFileSync(filePath, {encoding: 'UTF8'}); if (!this._cache[name]) this._cache[name] = {}; var template = this._cache[name] template.name = name; template.templateString = templateString; template.render = render function render(data) { return Q.promise(function(resolve, reject) { // TODO Not sure if this caches parsed templates behind the scenes? engine.parseAndRender(templateString, data) .then(resolve) .catch(reject); }); } } /** * Go through our template dir and read the template files * into memory as strings. * Assumes all templates fit into memory. */ OKTemplateRepo.prototype._populateCache = function _populateCache(engine, cache, ext) { var self = this; var files = glob.sync(this._globString); files.forEach(function eachFile(path) { self._loadTemplate(path); }); } module.exports = OKTemplateRepo;