UNPKG

9.09 kBJavaScriptView Raw
1/**
2 * views/index.js
3 * */
4
5"use strict";
6
7var pug = require('pug'),
8 path = require('path'),
9 fs = require('fs');
10
11module.exports = class {
12
13 constructor({request, response, controllerName = '', action = '', config, paths}) {
14 this.request = request;
15 this.response = response;
16 this.controllerName = controllerName;
17 this.actionName = action;
18 this.paths = paths;
19 this.config = config;
20
21 this.templateActive = true;
22 this.templateOptions = null;
23 this.renderContent = null;
24
25 if (this.config.template) {
26 this.templateName = this.templateNameDefault = this.config.template.name;
27
28 if (!path.extname(this.config.template.layout)) {
29 this.config.template.layout += '.pug';
30 }
31
32 this.templateLayout = this.templateLayoutDefault = this.config.template.layout;
33 }
34 else {
35 this.templateName = this.templateNameDefault = 'default';
36 this.templateLayout = this.templateLayoutDefault = 'default.pug';
37 }
38
39 this.errors = {
40 "100": "Continue",
41 "101": "Switching Protocols",
42 "102": "Processing",
43 "200": "OK",
44 "201": "Created",
45 "202": "Accepted",
46 "203": "Non-Authoritative Information",
47 "204": "No Content",
48 "205": "Reset Content",
49 "206": "Partial Content",
50 "207": "Multi-Status",
51 "208": "Already Reported",
52 "226": "IM Used",
53 "300": "Multiple Choices",
54 "301": "Moved Permanently",
55 "302": "Found",
56 "303": "See Other",
57 "304": "Not Modified",
58 "305": "Use Proxy",
59 "306": "Switch Proxy",
60 "307": "Temporary Redirect",
61 "308": "Permanent Redirect",
62 "400": "Bad Request",
63 "401": "Unauthorized",
64 "402": "Payment Required",
65 "403": "Forbidden",
66 "404": "Not Found",
67 "405": "Method Not Allowed",
68 "406": "Not Acceptable",
69 "407": "Proxy Authentication Required",
70 "408": "Request Timeout",
71 "409": "Conflict",
72 "410": "Gone",
73 "411": "Length Required",
74 "412": "Precondition Failed",
75 "413": "Payload Too Large",
76 "414": "URI Too Long",
77 "415": "Unsupported Media Type",
78 "416": "Range Not Satisfiable",
79 "417": "Expectation Failed",
80 "418": "I'm a teapot",
81 "421": "Misdirected Request",
82 "422": "Unprocessable Entity",
83 "423": "Locked",
84 "424": "Failed Dependency",
85 "426": "Upgrade Required",
86 "428": "Precondition Required",
87 "429": "Too Many Requests",
88 "431": "Request Header Fields Too Large",
89 "451": "Unavailable For Legal Reasons/Redirect",
90 "103": "Checkpoint",
91 "420": "Method Failure/Enhance Your Calm",
92 "450": "Blocked by Windows Parental Controls",
93 "498": "Invalid Token",
94 "499": "Token Required/Request has been forbidden by antivirus",
95 "509": "Bandwidth Limit Exceeded",
96 "530": "Site is frozen",
97 "440": "Login Timeout",
98 "449": "Retry With"
99 }
100
101 }
102
103 templatePath(template, layout) {
104 return path.join(paths.app.views, 'templates', this.templateName, this.templateLayout);
105 }
106
107 controller(controllerName, action) {
108 if (controllerName) {
109 this.controllerName = controllerName;
110 }
111
112 if (action) {
113 this.actionName = action;
114 }
115
116 return this;
117 }
118
119 http(request, response) {
120 this.response = response;
121
122 this.request = request;
123
124 return this;
125 }
126
127 setConfig({response, request, config, paths}) {
128 if (response) {
129 this.response = response;
130 }
131
132 if (response) {
133 this.request = request;
134 }
135
136 if (paths) {
137 this.paths = paths;
138 }
139
140 if (config) {
141 this.config = config;
142 }
143
144 return this;
145 }
146
147 error(error, message, options = {}) {
148 if (typeof error == 'object' && error['error']) {
149 options = error;
150 error = error.error;
151 message = null;
152 }
153
154 if (typeof message == 'object') {
155 options = message;
156 message = null;
157 }
158
159 this.response.status(error);
160
161 if (!options.error) {
162 options.error = error;
163 }
164
165 if (!options.message && !message) {
166 if (this.errors[error]) {
167 options.message = this.errors[error]
168 }
169 else {
170 options.message = ""
171 }
172 }
173
174 if (this.request.accepts('html')) {
175 return this.template(null, 'errors').render('errors/errors', options).send();
176 }
177
178 if (this.request.accepts('json')) {
179 return this.response.send(options);
180 }
181
182 return this.response.type('txt').send(options.error + ' - ' + options.message);
183 }
184
185 template(name, layout = 'default.pug', options = null) {
186 if (name === false) {
187 this.templateActive = false;
188 return this;
189 }
190 else if (name === null) {
191 name = this.templateName;
192 }
193
194 if (typeof name == 'object') {
195 this.templateOptions = name;
196 }
197 else if (typeof layout == 'object' && typeof name == 'string') {
198 this.templateOptions = layout;
199 this.templateName = name;
200 }
201 else {
202 if (!path.extname(layout)) {
203 layout += '.pug';
204 }
205
206 this.templateLayout = layout;
207 this.templateName = name;
208 this.templateOptions = options;
209 }
210
211 this.templateActive = true;
212
213 return this;
214 }
215
216 render(name, options) {
217 var viewPaths;
218
219 if (typeof name == 'object' || typeof name == 'array') {
220 options = name;
221 name = this.actionName;
222 }
223
224 if (!name) {
225 name = this.actionName;
226 }
227
228 if (!path.extname(name)) {
229 viewPaths = [
230 path.join(this.paths.app.views, this.controllerName, name + '.pug'),
231 path.join(this.paths.app.views, this.controllerName, name + '.jade'),
232 path.join(this.paths.app.views, this.controllerName, name + '.html'),
233 path.join(this.paths.app.views, name + '.pug'),
234 path.join(this.paths.app.views, name + '.jade'),
235 path.join(this.paths.app.views, name + '.html')
236 ]
237
238 }
239 else {
240 viewPaths = [
241 path.join(this.paths.app.views, this.controllerName, this.actionName, name),
242 path.join(this.paths.app.views, this.controllerName, name),
243 path.join(this.paths.app.views, name)
244 ]
245 }
246
247 for (var key in viewPaths) {
248 try {
249 if (path.extname(viewPaths[key]) == '.pug' || path.extname(filePath) == '.jade') {
250 return this.renderTemplate(pug.renderFile(viewPaths[key], options))
251 }
252
253 var html = fs.readFileSync(viewPaths[key]).toString();
254
255 if (options) {
256 html = pug.render('script var view = ' + JSON.stringify(options)) + "\n\n" + html;
257 }
258
259 return this.renderTemplate(html);
260 }
261 catch (e) {
262 //..
263 }
264 }
265
266 console.error(`Error: View /${this.controllerName}/${name} and /${name} not found`);
267 return this.error(404, options);
268 }
269
270 renderTemplate(content) {
271 if (!this.templateActive) {
272 this.renderContent = content;
273 }
274 else if (path.extname(this.templateLayout) == '.pug' || path.extname(this.templateLayout) == '.jade') {
275 if (this.templateOptions) {
276 this.templateOptions.content = content;
277 content = this.templateOptions;
278 this.templateOptions = null;
279 }
280 else {
281 content = {content}
282 }
283
284 this.renderContent = pug.renderFile(this.templatePath(), content)
285 }
286 else {
287 var html = fs.readFileSync(this.templatePath()).toString();
288
289 this.renderContent = pug.render('script var view = ' + JSON.stringify(content)) + "\n\n" + html;
290 }
291
292 this.templateName = this.templateNameDefault;
293 this.templateLayout = this.templateLayoutDefault;
294
295 return this;
296 }
297
298 send(content) {
299 if (content == undefined && this.renderContent) {
300 content = this.renderContent;
301 this.renderContent = null;
302 }
303
304 this.response.send(content);
305 }
306}
\No newline at end of file