-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathjade-middleware.js
141 lines (131 loc) · 4.61 KB
/
jade-middleware.js
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
var jade = require('jade');
var path = require('path');
var fs = require('fs');
// Debug logger
var useDebugLog = (typeof process.env.DEBUG_JADE_MIDDLEWARE !== "undefined");
var debugLog = function () {
if (!useDebugLog) { return; }
console.log.apply(this, Array.prototype.slice.call(arguments, 0));
};
// # Middleware
module.exports = function (options) {
var pages = {};
var src = options.src;
// used for jade extends
var jadeOptions = options.jadeOptions;
return function (req, res, next) {
hasHTMLExtension(req.url, function (yN, extension) {
// if not finish
if (!yN) {
next();
return;
}
hasMatchingJadeFileInPages(src, req.url, pages, jadeOptions, function (yN, page) {
if (yN) {
page.shouldRenderToFile(function (yN) {
if (yN) {
page.renderToFile(next);
} else {
next();
}
});
} else {
next();
}
});
});
};
};
// ## Utils
// see if request may be for an HTML file
function hasHTMLExtension(url, callback) {
var extension = path.extname(url);
if (extension === "" || extension === ".html" /* || extension === ".htm" */) {
return callback(true, extension);
} else {
return callback(false);
}
}
// creates a jade page if it doesn't exist in cache
function hasMatchingJadeFileInPages(srcDir, url, pages, jadeOptions, callback) {
if (typeof pages[url] === 'undefined') {
// get the possible jade file path
var extension = path.extname(url);
var jadeFilePath;
var htmlFilePath;
if (extension === ".html" /* || extension === ".htm" */) {
jadeFilePath = path.join(srcDir, url.substring(0, url.length - extension.length) + ".jade");
htmlFilePath = path.join(srcDir, url);
} else {
jadeFilePath = path.join(srcDir, url + "/index.jade");
htmlFilePath = path.join(srcDir, url + "/index.html");
}
// see if the jadefile exsists
fs.exists(jadeFilePath, function (exsits) {
// store the result in a new HTML page
pages[url] = new HTMLPage({
matchingJadeFilePath: (exsits)?jadeFilePath:null,
htmlFilePath: htmlFilePath,
jadeOptions: jadeOptions
});
callback(!!pages[url].matchingJadeFilePath, pages[url]);
});
} else {
callback(!!pages[url].matchingJadeFilePath, pages[url]);
}
}
// ## HTML Page Object
var HTMLPage = function (options) {
this.matchingJadeFilePath = options.matchingJadeFilePath;
this.htmlFilePath = options.htmlFilePath;
this.lastRenderToFile = undefined;
this.jadeOptions = (typeof options.jadeOptions === 'undefined') ? { pretty: true } : options.jadeOptions;
};
HTMLPage.prototype.shouldRenderToFile = function (callback) {
if (!!this.matchingJadeFilePath && !this.lastRenderToFile) {
callback(true);
} else if (!!this.matchingJadeFilePath) {
var self = this;
fs.stat(this.matchingJadeFilePath, function (err, stats) {
if (err) {
console.error("jade-middleware::Could not stat .jade file");
console.error(err);
callback(false);
return;
}
callback(self.lastRenderToFile < stats.mtime);
});
} else {
callback(false);
}
};
HTMLPage.prototype.renderToFile = function (callback) {
this.lastRenderToFile = Date.now();
debugLog("jade-middleware::renderToFile", this.lastRenderToFile );
var self = this;
fs.readFile(this.matchingJadeFilePath, function (err, data) {
data = data.toString();
if (err) {
console.error("jade-middleware::Could not read .jade file");
console.error(err);
callback();
return;
}
var compileError = false;
var jadeCompiledFn;
var jadeString;
try {
jadeCompiledFn = jade.compile(data, self.jadeOptions);
} catch (e) {
compileError = e.toString();
}
jadeString = (compileError) ? compileError : jadeCompiledFn();
fs.writeFile(self.htmlFilePath, jadeString, function (err) {
if (err) {
console.error("jade-middleware::Could not read .jade file");
console.error(err);
}
callback();
});
});
};