UNPKG

25.3 kBJavaScriptView Raw
1/*------------------------------------*\
2 RESPONSE
3\*------------------------------------*/
4/* jslint node: true */
5
6/**
7 * Get all information to prepare the response.
8 * @private
9 * @function prepareResponse
10 * @memberOf NA#
11 * @this NA
12 * @param {string} path The url listening.
13 * @param {Object} options Option associate to this url.
14 * @param {Object} request Initial request.
15 * @param {Object} response Initial response.
16 * @param {NA~callback} next Next step after.
17 */
18exports.prepareResponse = function (path, options, request, response, next) {
19 var NA = this,
20
21 /**
22 * All parameters from a specific page.
23 * @namespace routeParameters
24 * @public
25 * @alias routeParameters
26 * @type {Object}
27 * @memberOf NA#locals
28 */
29 routeParameters = options[path],
30
31 /**
32 * All locals provided for Views Template Engine and Hooks.
33 * @namespace locals
34 * @public
35 * @alias locals
36 * @type {Object}
37 * @memberOf NA#
38 */
39 locals = {
40
41 /**
42 * Expose route of current page from current webconfig `routes`.
43 * @public
44 * @alias route
45 * @type {string}
46 * @memberOf NA#locals
47 * @example /categories/:category/
48 */
49 route: path
50 };
51
52 /* path contain `{ view, controller, ... }` because `NA.webconfig.routes` is `[{ view, controller, ... }, ...]` */
53 if (typeof path === "object") {
54 routeParameters = path;
55 }
56
57 /* routeParameters contain `"index.htm"` because `NA.webconfig.routes["/"]` is `"index.htm"` not `{ view, controller, ... }` */
58 if (typeof routeParameters === 'string') {
59 routeParameters = {
60
61 /**
62 * This is the file name of view used for render of page behind the route.
63 * @public
64 * @alias view
65 * @type {string}
66 * @memberOf NA#locals.routeParameters
67 */
68 view: routeParameters
69 };
70 }
71
72 /* Case of `routeParameters.url` replace `path` because `path` is used like a key. */
73 if (routeParameters.url) {
74 locals.route = routeParameters.url;
75 }
76
77 if (routeParameters.url && typeof path === "string") {
78
79 /**
80 * Expose the key from `<currentRoute>` object from webconfig.
81 * @public
82 * @alias routeKey
83 * @type {Object}
84 * @memberOf NA#locals
85 */
86 locals.routeKey = path;
87 }
88 if (routeParameters.key) {
89 locals.routeKey = routeParameters.key;
90 }
91
92 /**
93 * Expose all data from `routes[<currentRoute>]` object from webconfig.
94 * @public
95 * @alias routeParameters
96 * @type {Object}
97 * @memberOf NA#locals
98 */
99 locals.routeParameters = routeParameters;
100
101 /**
102 * Expose all webconfig values.
103 * @public
104 * @alias webconfig
105 * @type {Object}
106 * @memberOf NA#locals
107 */
108 locals.webconfig = NA.webconfig;
109
110 /* Add preparation into response. */
111 if (response) {
112 response.locals = locals;
113 }
114
115 NA.prepareRenderLanguage(locals, request, response, next);
116};
117
118/**
119 * Create some variable for manage path for render.
120 * @private
121 * @function prepareRenderLanguage
122 * @memberOf NA#
123 * @this NA
124 * @param {Object} locals Local variables for the current page.
125 * @param {Object} request Information from request.
126 * @param {Object} response Information from response.
127 * @param {NA~callback} next Next step after.
128 */
129exports.prepareRenderLanguage = function (locals, request, response, next) {
130 var NA = this;
131
132 /**
133 * Expose the current language code for the page if setted else expose the global if setted.
134 * @public
135 * @alias languageCode
136 * @type {string}
137 * @memberOf NA#locals
138 * @default undefined
139 */
140 locals.languageCode =
141
142 /**
143 * Represent the language code for this page.
144 * @public
145 * @alias languageCode
146 * @type {string}
147 * @memberOf NA#locals.routeParameters
148 * @default undefined
149 */
150 locals.routeParameters.languageCode ||
151
152 /**
153 * Represent the global and main language code for website.
154 * @public
155 * @alias languageCode
156 * @type {string}
157 * @memberOf NA#webconfig
158 * @default undefined.
159 */
160 NA.webconfig.languageCode;
161
162 /* Next preparation render for variation. */
163 NA.prepareRenderPath(locals, request, response, next);
164};
165
166/**
167 * Create some variable for manage path for render.
168 * @private
169 * @function prepareRenderPath
170 * @memberOf NA#
171 * @this NA
172 * @param {Object} locals Local variables for the current page.
173 * @param {Object} request Information from request.
174 * @param {Object} response Information from response.
175 * @param {NA~callback} next Next step after.
176 */
177exports.prepareRenderPath = function (locals, request, response, next) {
178 var NA = this,
179 path = NA.modules.path,
180 url = NA.modules.url,
181 query = (request && request.originalUrl && request.originalUrl.split("?"));
182
183 /**
184 * Idem as `NA#webconfig.urlRoot`.
185 * @public
186 * @alias urlRootPath
187 * @type {string}
188 * @memberOf NA#locals
189 * @example http://localhost:7777
190 * https://www.example.here
191 */
192 locals.urlRootPath = NA.webconfig.urlRoot;
193
194 /**
195 * Idem as `NA#webconfig.urlRelativeSubPath`.
196 * @public
197 * @alias urlSubPath
198 * @type {string}
199 * @memberOf NA#locals
200 * @example /subpath
201 */
202 locals.urlSubPath = NA.webconfig.urlRelativeSubPath;
203
204 /**
205 * Expose the current URL of page with `NA#webconfig.urlRoot` and `NA#webconfig.urlRelativeSubPath`.
206 * @public
207 * @alias urlBasePath
208 * @type {string}
209 * @memberOf NA#locals
210 * @example http://localhost:7777/subpath
211 * https://www.example.here
212 */
213 locals.urlBasePath = NA.webconfig.urlRoot + NA.webconfig.urlRelativeSubPath;
214
215 /**
216 * Url from `url` value for current route.
217 * @public
218 * @alias urlFilePath
219 * @type {string}
220 * @memberOf NA#locals
221 * @example /example.html
222 * /example/this/
223 */
224 locals.urlFilePath = locals.routeParameters.output || locals.routeParameters.url;
225 if (request) {
226 locals.urlFilePath = url.format(path.join("/", request.url.replace(new RegExp("^/?" + locals.urlSubPath), "")));
227 }
228
229 /**
230 * Query from `url` value for current route.
231 * @public
232 * @alias urlQueryPath
233 * @type {string}
234 * @memberOf NA#locals
235 * @example ?title=Haeresis&description=ok
236 * ?title=Haeresis
237 */
238 locals.urlQueryPath = query && query[1] ? "?" + query[1] : "";
239
240 /**
241 * Expose the current URL of page with `NA#webconfig.urlBasePath` and the current page route.
242 * @public
243 * @alias urlPath
244 * @type {string}
245 * @memberOf NA#locals
246 * @example http://localhost:7777/subpath/example.html?title=Haeresis&description=ok
247 * https://www.example.here/example/this/?title=Haeresis
248 */
249 locals.urlPath = locals.urlBasePath + locals.route + locals.urlQueryPath;
250 if (request) {
251 locals.urlPath = "http" + ((NA.webconfig.httpSecure) ? "s" : "") + '://' + request.get("host") + request.originalUrl;
252 }
253
254 /* Next preparation render for variation. */
255 NA.prepareRenderVariation(locals, request, response, next);
256};
257
258/**
259 * Create some variable for manage variation into render.
260 * @private
261 * @function prepareRenderVariation
262 * @memberOf NA#
263 * @this NA
264 * @param {Object} locals Local variables for the current page.
265 * @param {Object} request Information from request.
266 * @param {Object} response Information from response.
267 * @param {NA~callback} next Next step after.
268 */
269exports.prepareRenderVariation = function (locals, request, response, next) {
270 var NA = this,
271 extend = NA.modules.extend,
272 async = NA.modules.async;
273
274 if (request) {
275
276 /**
277 * Expose list of slug parameters used into URL.
278 * @public
279 * @alias params
280 * @type {string}
281 * @memberOf NA#locals
282 * @example If current route is '/example/:selector/'
283 * At http://localhost/example/test/ the value of `NA.locals#params` is
284 * { "selector": "test" }
285 */
286 locals.params = request.params || {};
287
288 /**
289 * Expose list of query parameters used into URL.
290 * @public
291 * @alias query
292 * @type {string}
293 * @memberOf NA#locals
294 * @example At http://localhost/example/?param=test the value of `NA.locals#query` is
295 * { "param": "test" }
296 */
297 locals.query = request.query || {};
298
299 /**
300 * Expose list of body parameters used into page.
301 * @public
302 * @alias body
303 * @type {string}
304 * @memberOf NA#locals
305 * @example If the Response body is `test=This+is+a+test` the value of `NA.locals#body` is
306 * { "test": "This is a test" }
307 */
308 locals.body = request.body || {};
309 }
310
311 async.parallel([
312 function (callback) {
313
314 /**
315 * Name of file for `common` variation.
316 * @public
317 * @alias variation
318 * @type {string}
319 * @memberOf NA#webconfig
320 */
321 locals.common = NA.openVariation(NA.webconfig.variation, locals.languageCode);
322 if (locals.languageCode) {
323
324 /**
325 * Expose all JSON data from `variation` file.
326 * @public
327 * @alias common
328 * @type {Object}
329 * @memberOf NA#locals
330 */
331 locals.common = extend(true, NA.openVariation(NA.webconfig.variation, undefined, true), locals.common);
332 }
333
334 callback();
335 },
336 function (callback) {
337
338 /**
339 * Name of file for `specific` variation.
340 * @public
341 * @alias variation
342 * @type {string}
343 * @memberOf NA#locals.routeParameters
344 */
345 locals.specific = NA.openVariation(locals.routeParameters.variation, locals.languageCode);
346 if (locals.languageCode) {
347
348 /**
349 * Expose all JSON data from `routes[<currentRoute>].variation` file.
350 * @public
351 * @alias specific
352 * @type {Object}
353 * @memberOf NA#locals
354 */
355 locals.specific = extend(true, NA.openVariation(locals.routeParameters.variation, undefined, true), locals.specific);
356 }
357
358 callback();
359 }
360 ], function () {
361
362 /* Nexts Step for render. */
363 NA.prepareHeaders(locals, request, response, next);
364 });
365};
366
367/**
368 * Add and Remove headers from Webconfig.
369 * @private
370 * @function manageHeaders
371 * @memberOf NA~
372 * @param {NA} NA NodeAtlas instance.
373 * @param {Object} headers All headers from webconfig.
374 * @param {Object} response All stuff for HTTP response.
375 */
376function manageHeaders(NA, headers, response) {
377 var header;
378
379 for (header in NA.webconfig.headers) {
380 if (!NA.webconfig.headers.hasOwnProperty(header)) {
381 continue;
382 }
383 if (NA.webconfig.headers[header] === false) {
384 response.removeHeader(header);
385 } else {
386 response.setHeader(header, NA.webconfig.headers[header]);
387 }
388 }
389 for (header in headers) {
390 if (!headers.hasOwnProperty(header)) {
391 continue;
392 }
393 if (headers[header] === false) {
394 response.removeHeader(header);
395 } else {
396 response.setHeader(header, headers[header]);
397 }
398 }
399}
400
401/**
402 * Set all webconfig headers.
403 * @private
404 * @function prepareHeaders
405 * @memberOf NA#
406 * @this NA
407 * @param {Object} locals Local variables for the current page.
408 * @param {Object} request Information from request.
409 * @param {Object} response Information from response.
410 * @param {NA~callback} next Next step after.
411 */
412exports.prepareHeaders = function (locals, request, response, next) {
413 var NA = this,
414
415 /**
416 * Charset used for render of this page.
417 * @public
418 * @alias charset
419 * @type {string}
420 * @memberOf NA#locals.routeParameters
421 * @default "utf-8"
422 */
423 charset = locals.routeParameters.charset || NA.webconfig.charset,
424
425 /**
426 * Content Type used for respond with this page.
427 * @public
428 * @alias mimeType
429 * @type {string}
430 * @memberOf NA#locals.routeParameters
431 * @default "text/html"
432 */
433 mimeType = locals.routeParameters.mimeType || NA.webconfig.mimeType,
434
435 /**
436 * Status Code used for respond with this page.
437 * @public
438 * @alias statusCode
439 * @type {number}
440 * @memberOf NA#locals.routeParameters
441 * @default 200
442 */
443 statusCode = locals.routeParameters.statusCode || 200,
444
445 /**
446 * Headers value used for respond with this page.
447 * @public
448 * @alias mimeType
449 * @type {string}
450 * @memberOf NA#locals.routeParameters
451 * @default "text/html"
452 */
453 headers = locals.routeParameters.headers || {};
454
455 if (response) {
456 /* Set charset and */
457 response.statusCode = statusCode;
458
459 /* Set headers into response */
460 response.setHeader("Content-Type", mimeType + ";" + " charset=" + charset);
461 manageHeaders(NA, headers, response);
462 }
463
464 /* Nexts Step for render. */
465 next(locals, request, response);
466};
467
468/**
469 * Intercept Variation from common file.
470 * @private
471 * @function changeVariationsCommon
472 * @memberOf NA#
473 * @this NA
474 * @param {Object} locals Local variables for the current page.
475 * @param {Object} request Information from request.
476 * @param {Object} response Information from response.
477 * @param {NA~callback} next Next step after.
478 */
479exports.changeVariationsCommon = function (locals, request, response, next) {
480 var NA = this;
481
482 /* Loading the controller file if `routeParameters.controller` exist. */
483 NA.openController(
484
485 /**
486 * This is the file name of specific controller used for back-end part of this page.
487 * @public
488 * @alias controller
489 * @type {string}
490 * @memberOf NA#locals.routeParameters
491 */
492 locals.routeParameters.controller);
493
494 /* Use the `NA.controllers[<controller>].changeVariations(...)` function if set... */
495 if (typeof NA.controllers[NA.webconfig.controller] !== 'undefined' &&
496 typeof NA.controllers[NA.webconfig.controller].changeVariations !== 'undefined') {
497
498 /**
499 * Define this function for intercept Variation object and modify it. Both `common` and `specific` controller.
500 * @function changeVariations
501 * @memberOf NA#controllers[]
502 * @param {changeVariations~callback} callback Next steps after configuration is done.
503 * @param {Object} locals Local variables object of current page.
504 * @param {Object} response Initial response.
505 * @param {Object} request Initial request.
506 */
507 NA.controllers[NA.webconfig.controller].changeVariations.call(NA,
508
509 /**
510 * Next steps after changeVariations is done.
511 * @callback changeVariations~callback
512 */
513 function () {
514 NA.changeVariationsSpecific(locals, request, response, next);
515 }, locals, request, response);
516 /* ...else, just continue. */
517 } else {
518 NA.changeVariationsSpecific(locals, request, response, next);
519 }
520};
521
522/**
523 * Intercept Variation from specific file.
524 * @private
525 * @function changeVariationsSpecific
526 * @memberOf NA#
527 * @this NA
528 * @param {Object} locals Local variables for the current page.
529 * @param {Object} request Information from request.
530 * @param {Object} response Information from response.
531 * @param {NA~callback} next Next step after.
532 */
533exports.changeVariationsSpecific = function (locals, request, response, next) {
534 var NA = this;
535
536 if (typeof NA.controllers[locals.routeParameters.controller] !== 'undefined' &&
537 typeof NA.controllers[locals.routeParameters.controller].changeVariations !== 'undefined') {
538 /* Use the `NA.controllers[<controller>].changeVariations(...)` function if set... */
539 NA.controllers[locals.routeParameters.controller].changeVariations.call(NA, function () {
540 NA.changeDomCommon(locals, request, response, next);
541 }, locals, request, response);
542 } else {
543 /* ...else, just continue. */
544 NA.changeDomCommon(locals, request, response, next);
545 }
546};
547
548/**
549 * Prepare the choosen engine to parse view.
550 * @private
551 * @function prepareEngineProcess
552 * @memberOf NA~
553 * @param {NA} NA NodeAtlas instance.
554 * @param {Object} locals Local variables for the current page.
555 * @param {Object} response Information from response.
556 * @param {NA~callback} next Next step after.
557 */
558function prepareEngineProcess(NA, locals, response, next) {
559 var ejs = NA.modules.ejs,
560 pug = NA.modules.pug,
561 pathM = NA.modules.path,
562 engine = NA.webconfig.pug ? pug : ejs,
563 path = NA.modules.path,
564 view = path.join(NA.serverPath, NA.webconfig.viewsRelativePath, (
565
566 /**
567 * Name of file for `common` view.
568 * @public
569 * @alias view
570 * @type {string}
571 * @memberOf NA#webconfig
572 */
573 NA.webconfig.view) ? NA.webconfig.view : (locals.routeParameters.view || ""));
574
575 if (typeof locals.routeParameters.pug === "boolean") {
576
577 /**
578 * Allow you to enable Pug only for a page.
579 * @public
580 * @alias pug
581 * @type {boolean}
582 * @memberOf NA#locals.routeParameters
583 * @default undefined
584 */
585 engine = locals.routeParameters.pug ? pug : ejs;
586 }
587
588 /* Without view, no data. */
589 if (!locals.routeParameters.view) {
590 return next("");
591 }
592
593 /**
594 * Allow template engine know which file is currently in use.
595 * @public
596 * @alias filename
597 * @type {string}
598 * @memberOf NA#locals
599 */
600 locals.filename = pathM.join(NA.serverPath, NA.webconfig.viewsRelativePath, NA.webconfig.view || locals.routeParameters.view);
601
602 engineProcess(NA, view, engine, locals, response, next);
603}
604
605/**
606 * Choose an engine to parse view.
607 * @private
608 * @function engineProcess
609 * @memberOf NA~
610 * @param {NA} NA NodeAtlas instance.
611 * @param {string} view View to parse.
612 * @param {string} engine Engine to parse.
613 * @param {Object} locals Local variables for the current page.
614 * @param {Object} response Information from response.
615 * @param {NA~callback} next Next step after.
616 */
617function engineProcess(NA, view, engine, locals, response, next) {
618 if (NA.webconfig.engine) {
619
620 /* Transform from any engine but globaly. */
621 response.render(view, locals, function (err, data) {
622 if (err) {
623 data = err.toString();
624 }
625
626 next(data);
627 });
628 } else {
629 /* Open the template file */
630 NA.openView(locals.routeParameters, view, function (data) {
631
632 /* Transform ejs/pug data and inject incduded file. */
633 try {
634 data = engine.render(data, locals);
635 } catch (err) {
636 /* Make error more readable. */
637 data = err.toString()
638 .replace(/</g, "&lt;")
639 .replace(/[\n]/g, "<br>")
640 .replace(/\t/g, "<span style='display:inline-block;width:32px'></span>")
641 .replace(/ /g, "<span style='display:inline-block;width:32px'></span>")
642 .replace(/ /g, "<span style='display:inline-block;width:32px'></span>")
643 .replace(/ /g, "<span style='display:inline-block;width:32px'></span>")
644 .replace(/ >> /g, "<span style='display:inline-block;width:32px'>&gt;&gt;</span>")
645 .replace(/> ([0-9])+\|/g, "<span style='display:inline-block;margin-left:-13px'>> $1|</span>")
646 .replace(/^([a-zA-Z]+):/g, "$1:<br><br>");
647 }
648
649 next(data);
650 });
651 }
652}
653
654/**
655 * Intercept DOM from common file.
656 * @private
657 * @function changeDomCommon
658 * @memberOf NA#
659 * @param {Object} locals Local variables for the current page.
660 * @param {Object} request Information from request.
661 * @param {Object} response Information from response.
662 * @param {NA~callback} next Next step after.
663 */
664exports.changeDomCommon = function (locals, request, response, next) {
665 var NA = this;
666
667 // Transform into HTML
668 prepareEngineProcess(NA, locals, response, function (data) {
669
670 /**
671 * The compiled HTML of view + locals provided by response.
672 * @public
673 * @alias dom
674 * @type {string}
675 * @memberOf NA#locals
676 */
677 locals.dom = data;
678
679 /* Use the `NA.controllers[<controller>].changeDom(...)` function if set... */
680 if (typeof NA.controllers[NA.webconfig.controller] !== 'undefined' &&
681 typeof NA.controllers[NA.webconfig.controller].changeDom !== 'undefined') {
682
683 /**
684 * Generate a virtual DOM to use jQuery on it.
685 * @function virtualDom
686 * @memberOf NA#locals
687 * @returns {Object} The $ object to manipulate the virtual DOM.
688 */
689 locals.virtualDom = function () {
690 var jsdom = NA.modules.jsdom;
691 return new jsdom.JSDOM(data);
692 };
693
694 /**
695 * Define this function for intercept DOM and modify it with jQuery for example. Both `common` and `specific` controller.
696 * @function changeDom
697 * @memberOf NA#controllers[]
698 * @param {changeDom~callback} callback Next steps after configuration is done.
699 * @param {Object} locals Local variables for the current page.
700 * @param {string} locals.dom DOM of current page.
701 * @param {Object} response Initial response.
702 * @param {Object} request Initial request.
703 */
704 NA.controllers[NA.webconfig.controller].changeDom.call(NA,
705
706 /**
707 * Next steps after changeDomSpecific is done.
708 * @callback changeDomSpecific~callback
709 * @param {Object} dom DOM with modifications.
710 */
711 function (dom) {
712 if (typeof dom === "object") {
713 locals.dom = dom.serialize();
714 }
715 NA.changeDomSpecific(locals, request, response, next);
716 }, locals, request, response);
717 /* ...else, just continue. */
718 } else {
719 NA.changeDomSpecific(locals, request, response, next);
720 }
721 });
722};
723
724/**
725 * Intercept DOM from specific file.
726 * @private
727 * @function changeDomSpecific
728 * @memberOf NA#
729 * @param {Object} locals Local variables for the current page.
730 * @param {Object} request Information from request.
731 * @param {Object} response Information from response.
732 * @param {NA~callback} next Next step after.
733 */
734exports.changeDomSpecific = function (locals, request, response, next) {
735 var NA = this;
736
737 if (typeof NA.controllers[locals.routeParameters.controller] !== 'undefined' &&
738 typeof NA.controllers[locals.routeParameters.controller].changeDom !== 'undefined') {
739
740 locals.virtualDom = function () {
741 var jsdom = NA.modules.jsdom;
742 return new jsdom.JSDOM(data);
743 };
744
745 /** Use the `NA.controllers[<controller>].changeVariations(...)` function if set... */
746 NA.controllers[locals.routeParameters.controller].changeDom.call(NA, function (dom) {
747 if (typeof dom === "object") {
748 locals.dom = dom.serialize();
749 }
750 NA.intoBrowserAndFiles(locals, request, response, next);
751 }, locals, request, response);
752 } else {
753 /** ...else, just continue. */
754 NA.intoBrowserAndFiles(locals, request, response, next);
755 }
756};
757
758/**
759 * Inject CSS into DOM if needed.
760 * @private
761 * @function intoBrowserAndFiles
762 * @memberOf NA#
763 * @param {Object} locals Local variables for the current page.
764 * @param {Object} request Information from request.
765 * @param {Object} response Information from response.
766 * @param {NA~callback} next Next step after.
767 */
768exports.intoBrowserAndFiles = function (locals, request, response, next) {
769 var NA = this;
770
771 /* Inject CSS into DOM... */
772 if (NA.webconfig.injectCss || locals.routeParameters.injectCss) {
773 NA.injectCss(locals.dom, locals.routeParameters.injectCss, function (dom) {
774 NA.renderTemplate(dom, locals, request, response, next);
775 });
776 /* ...or do nothing. */
777 } else {
778 NA.renderTemplate(locals.dom, locals, request, response, next);
779 }
780};
781
782/**
783 * Write file or/and send response.
784 * @private
785 * @function renderTemplate
786 * @memberOf NA#
787 * @param {string} data HTML DOM ready for sending.
788 * @param {Object} locals Local variables for the current page.
789 * @param {Object} request Information from request.
790 * @param {Object} response Information from response.
791 * @param {NA~callback} next Next step after.
792 */
793exports.renderTemplate = function (data, locals, request, response, next) {
794 var NA = this,
795 async = NA.modules.async,
796
797 /**
798 * Allow NodeAtlas to generate real file into `NA#webconfig.serverlessRelativePath` directory if set to true.
799 * @public
800 * @alias htmlGenerationBeforeResponse
801 * @type {boolean}
802 * @memberOf NA#webconfig
803 * @default false
804 */
805 htmlGenerationBeforeResponse = NA.webconfig.htmlGenerationBeforeResponse,
806 output = (typeof NA.webconfig.output === 'boolean') ? NA.webconfig.output : true,
807 templateRenderName;
808
809 /* Create the file for asset mode */
810 if (typeof response === "undefined" || (htmlGenerationBeforeResponse && output)) {
811
812 /**
813 * Output name of file generate if `NA#webconfig.htmlGenerationBeforeResponse` is set to true or if `--generate` command is used.
814 * If value is set to `false`, no generate page will be generated.
815 * @public
816 * @alias output
817 * @type {string|boolean}
818 * @memberOf NA#locals.routeParameters
819 */
820 templateRenderName = locals.route;
821
822 if (typeof locals.routeParameters.output !== 'undefined') {
823 templateRenderName = locals.routeParameters.output;
824 }
825
826 NA.saveRender(data, templateRenderName);
827 }
828
829 /* Run page into browser. */
830 if (typeof response !== "undefined") {
831 /* Compression of CSS, JS and Images if required. */
832 async.parallel([
833 NA.cssCompilation.bind(NA),
834 NA.jsObfuscation.bind(NA)
835 ], function () {
836 NA.sendResponse(request, response, data, next);
837 });
838 }
839};
\No newline at end of file