feature: root option allows array of strings

This commit is contained in:
harttle
2016-10-31 23:21:28 +08:00
parent 377c805230
commit 6dd836f157
18 changed files with 313 additions and 106 deletions
+33 -30
View File
@@ -1,6 +1,9 @@
const Scope = require('./src/scope');
const _ = require('./src/util/underscore.js');
const tokenizer = require('./src/tokenizer.js');
const fs = require('fs');
const statFileAsync = require('./src/util/fs.js').statFileAsync;
const readFileAsync = require('./src/util/fs.js').readFileAsync;
const pathResolve = require('./src/util/fs.js').pathResolve;
const Render = require('./src/render.js');
const lexical = require('./src/lexical.js');
const Tag = require('./src/tag.js');
@@ -10,6 +13,7 @@ const Syntax = require('./src/syntax.js');
const tags = require('./tags');
const filters = require('./filters');
const Promise = require('any-promise');
const someSeries = require('./src/util/promise.js').someSeries;
var _engine = {
init: function(tag, filter, options) {
@@ -53,7 +57,7 @@ var _engine = {
}
},
renderFile: function(filepath, ctx, opts) {
return this.handleCache(filepath)
return this.getTemplate(filepath)
.then((templates) => {
return this.render(templates, ctx, opts);
})
@@ -72,30 +76,34 @@ var _engine = {
registerTag: function(name, tag) {
return this.tag.register(name, tag);
},
handleCache: function(filepath) {
if (!filepath) throw new Error('filepath cannot be null');
return this.getTemplate(filepath)
.then((html) => {
var tpl = this.options.cache && this.cache[filepath] || this.parse(html);
return this.options.cache ? (this.cache[filepath] = tpl) : tpl;
});
lookup: function(filepath) {
var paths = this.options.root.map(root => pathResolve(root, filepath));
return someSeries(paths, path => statFileAsync(path).then(() => path));
},
getTemplate: function(filepath) {
filepath = resolvePath(this.options.root, filepath);
if (!filepath.match(/\.\w+$/)) {
filepath += this.options.extname;
}
return new Promise(function(resolve, reject) {
fs.readFile(filepath, 'utf8', function(err, html) {
err ? reject(err) : resolve(html);
return this
.lookup(filepath)
.then(filepath => {
if (this.options.cache) {
var tpl = this.cache[filepath];
if (tpl) {
return Promise.resolve(tpl);
}
return readFileAsync(filepath)
.then(str => this.parse(str))
.then(tpl => this.cache[filepath] = tpl);
} else {
return readFileAsync(filepath).then(str => this.parse(str));
}
});
});
},
express: function(renderingOptions) {
express: function(renderOption) {
renderOption = renderOption || {};
return (filePath, options, callback) => {
this.renderFile(filePath, options, renderingOptions)
this.renderFile(filePath, options, renderOption)
.then(html => callback(null, html))
.catch(e => callback(e));
};
@@ -104,7 +112,9 @@ var _engine = {
function factory(options) {
options = options || {};
options.root = options.root || '';
options.root = normalizeStringArray(options.root);
if (!options.root.length) options.root = ['.'];
options.extname = options.extname || '.liquid';
var engine = Object.create(_engine);
@@ -113,17 +123,10 @@ function factory(options) {
return engine;
}
function resolvePath(root, path) {
if (path[0] == '/') return path;
var arr = root.split('/').concat(path.split('/'));
var result = [];
arr.forEach(function(slug) {
if (slug == '..') result.pop();
else if (!slug || slug == '.');
else result.push(slug);
});
return '/' + result.join('/');
function normalizeStringArray(value) {
if (_.isArray(value)) return value;
if (_.isString(value)) return [value];
return [];
}
factory.lexical = lexical;