UNPKG

4.34 kBJavaScriptView Raw
1var _ = require('lodash'),
2 async = require('async'),
3 mkdirp = require('mkdirp'),
4 f = require('file'),
5 fs = require('fs'),
6 functions = require('./functions'),
7 jazz = require('jazz'),
8 p = require('path');
9
10/**
11 * class Engine
12 *
13 * @param {String} opts: optional
14 * - ext: template file extension, files without this extension will be ignored.
15 * - mkdirp: temporary used for testing only, need to figure out how to mock required function using Sinon
16 */
17function Engine(opts) {
18 opts = opts || {};
19 this.ext = opts.ext || 'html';
20 mkdirp = opts.mkdirp || mkdirp;
21}
22
23/**
24 * Compile all template files (identified by file extension) in a directory.
25 * This can be done in parallel because compiling a template does not depend on other templates.
26 *
27 * @param {String} dir: directory containing the templates
28 * @param {Function} cb: standard cb(err, result) callback
29 */
30Engine.prototype.compile = function (dir, cb) {
31
32 var tasks = {},
33 self = this;
34
35 function _task(base, file) {
36 var baseFile = p.join(base, file),
37 baseUrlPath = baseFile.replace(/\\/g, '/');
38 tasks[baseUrlPath.substr(baseUrlPath.indexOf('/') + 1)] = function (cb) {
39 fs.readFile(baseFile, 'utf8', function (err, result) {
40 cb(err, jazz.compile(result));
41 });
42 };
43 }
44
45 f.walkSync(dir, function (base, dirs, files) {
46 files.forEach(function (file) {
47 if (file.match(new RegExp('\\.' + self.ext))) {
48 _task(base, file);
49 }
50 });
51 });
52
53 async.parallel(tasks, cb);
54};
55
56/**
57 * Compile all template files (identified by file extension) in a directory.
58 * This can be done in parallel because compiling a template does not depend on other templates.
59 *
60 * @param {String} dir: output directory where website files will be written to
61 * @param {Object} templates: compiled jazz templates
62 * @param {Object} params: template parameters and functions
63 * @param {Function} cb: standard cb(err, result) callback
64 */
65Engine.prototype.merge = function (dir, templates, params, cb) {
66
67 // merge a set of params to a set of templates
68 function _process(templates, params, cb) {
69 var _templates = _.extend(templates, {}), // process template copies, not the originals
70 tasks = {};
71
72 _.keys(_templates).forEach(function (key) {
73 tasks[key] = function (cb) {
74 _templates[key].process(params, function (data) {
75 cb(null, data);
76 });
77 };
78 });
79
80 async.parallel(tasks, function (err, results) {
81 cb(results);
82 });
83 }
84
85 var tasks = {};
86
87 _.keys(templates.pages).forEach(function (page) {
88 tasks[page] = function (cb) {
89
90 var pageParams = _.extend(_.extend({}, params), functions(page, templates, params)),
91 pageContent;
92
93 function _mergePartials(cb) {
94 _process(templates.partials, pageParams, function (result) {
95 pageParams.partials = result;
96 pageParams = _.extend(pageParams, functions(page, templates, pageParams));
97 _process(templates.partials, pageParams, function (result) {
98 pageParams.partials = result;
99 cb();
100 });
101 });
102 }
103
104 function _mergePage(cb) {
105 _process({ currpage: templates.pages[page] }, pageParams, function (result) {
106 pageParams.content = result.currpage;
107 cb();
108 });
109 }
110
111 function _mergeLayout(cb) {
112 var layout = (pageParams.sitemap && pageParams.sitemap[page] && pageParams.sitemap[page].layout) ? pageParams.sitemap[page].layout : 'default.html';
113 _process({ currlayout: templates.layouts[layout] }, pageParams, function (result) {
114 pageContent = result.currlayout;
115 cb();
116 });
117 }
118
119 function _writePage(cb) {
120 mkdirp(p.join(dir, page).replace(/(\/[^\/]+$|\\[^\\]+$)/, ''), '0755', function (err) {
121 if (!err) {
122 fs.writeFile(p.join(dir, page), pageContent, 'utf8', function (err) {
123 if (!err) {
124 console.log('+ creating %s', p.join(dir, page));
125 }
126 cb(err);
127 });
128 } else {
129 cb(err);
130 }
131 });
132 }
133
134 async.series([_mergePartials, _mergePage, _mergeLayout, _writePage], cb);
135 };
136 });
137
138 async.parallel(tasks, function (err, results) {
139 cb(err, _.keys(results));
140 });
141};
142
143module.exports = Engine;