summaryrefslogtreecommitdiff
path: root/app/node_modules/oktemplate/index.js
blob: ae9d1b16c81f758d2e54ffc9d77c76ef46fcb249 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
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 '<pre>' + stringify(obj) + '</pre>';
    } 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 Mustache 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;