Files
zulip/frontend_tests/zjsunit/render.js
Steve Howell 84c9be45af node tests: Remove requirement to test all templates.
We have less urgency to test all templates now.  The
most common error is probably unbalanced tags, and our
python-based template checker catches those problems
pretty well.

It's still possible to create bad templates, of course,
but the node tests have never been super deep at finding
semantic errors.
2018-05-24 09:30:22 -07:00

128 lines
3.2 KiB
JavaScript

var render = (function () {
var exports = {};
var fs = require('fs');
var _ = require('node_modules/underscore/underscore.js');
var Handlebars = require('handlebars');
function template_dir() {
return __dirname + '/../../static/templates/';
}
exports.init = function () {
Handlebars.templates = {};
};
exports.render_template = function (name, args) {
exports.compile_template(name);
return global.templates.render(name, args);
};
exports.compile_template = function (name) {
var included_fns = exports.find_included_partials(name);
_.each(included_fns, function (fn) {
exports.compile_template(fn);
});
if (Handlebars.templates === undefined) {
Handlebars.templates = {};
}
if (_.has(Handlebars.template, name)) {
// we already compile the template
return;
}
var file = exports.template_finder.get(name);
var data = fs.readFileSync(file.url).toString();
Handlebars.templates[name] = Handlebars.compile(data);
};
// list all files in a directory and it's subdirectories in a recursive sync way.
exports.walk = function (dir, filelist) {
filelist = filelist || [];
// grab files one level deep.
var files = fs.readdirSync(dir);
// for each file, check if it's a directory. If so, continue recursion.
// if not add to the file list.
files.forEach(function (file) {
if (fs.statSync(dir + "/" + file).isDirectory()) {
filelist = exports.walk(dir + "/" + file, filelist);
} else {
filelist.push({
url: dir + "/" + file,
name: file,
});
}
});
// return all recursively found files.
return filelist;
};
exports.template_finder = (function () {
// This class lets you find template files in our file system.
// It may be slightly overkill for our flat directory system;
// it might make more sense to just do something more like
// this: get_template_dir() + name + '.handlebars'
var self = {};
// get all files and then map them into friendlier names.
var all_files = exports.walk(template_dir());
var files = all_files
.filter(function (file) {
return (/\.handlebars$/).test(file.name);
})
.map(function (file) {
return {
url: file.url,
name: file.name.replace(/\.handlebars$/, ""),
};
});
self.get = function (name) {
var file = files.find(function (file) {
return file.name === name;
});
assert(file);
return file;
};
self.get_all = function () {
return files;
};
return self;
}());
exports.find_included_partials = function (name) {
var file = exports.template_finder.get(name);
assert(file);
var template = fs.readFileSync(file.url, "utf8");
var lst = [];
// match partial tags.
// this uses String.prototype.replace which is kind of hacky but
// it is the only JS function IIRC that allows you to match all
// instances of a pattern AND return capture groups.
template.replace(/\{\{\s*partial\s*"(.+?)"/ig, function (match, $1) {
lst.push($1);
});
return lst;
};
return exports;
}());
module.exports = render;