SFRA Server-side Javascript - Source: modules/server/render.js menu

SFRA / Server-side JS / Source: modules/server/render.js

  1. 'use strict';
  2. /* global XML */
  3. var isml = require('dw/template/ISML');
  4. var PageMgr = require('dw/experience/PageMgr');
  5. /**
  6. * Render an ISML template
  7. * @param {string} view - Path to an ISML template
  8. * @param {Object} viewData - Data to be passed as pdict
  9. * @param {Object} response - Response object
  10. * @returns {void}
  11. */
  12. function template(view, viewData) {
  13. // create a shallow copy of the data
  14. var data = {};
  15. Object.keys(viewData).forEach(function (key) {
  16. data[key] = viewData[key];
  17. });
  18. try {
  19. isml.renderTemplate(view, data);
  20. } catch (e) {
  21. throw new Error(e.javaMessage + '\n\r' + e.stack, e.fileName, e.lineNumber);
  22. }
  23. }
  24. /**
  25. * Render JSON as an output
  26. * @param {Object} data - Object to be turned into JSON
  27. * @param {Object} response - Response object
  28. * @returns {void}
  29. */
  30. function json(data, response) {
  31. response.setContentType('application/json');
  32. response.base.writer.print(JSON.stringify(data, null, 2));
  33. }
  34. /**
  35. * Render XML as an output
  36. * @param {Object} viewData - Object to be turned into XML
  37. * @param {Object} response - Response object
  38. * @returns {void}
  39. */
  40. function xml(viewData, response) {
  41. var XML_CHAR_MAP = {
  42. '<': '&lt;',
  43. '>': '&gt;',
  44. '&': '&amp;',
  45. '"': '&quot;',
  46. "'": '&apos;'
  47. };
  48. // Valid XML needs a single root.
  49. var xmlData = '<response>';
  50. Object.keys(viewData).forEach(function (key) {
  51. if (key === 'xml') {
  52. xmlData += viewData[key];
  53. } else {
  54. xmlData +=
  55. '<' + key + '>' + viewData[key].replace(/[<>&"']/g, function (ch) {
  56. return XML_CHAR_MAP[ch];
  57. }) + '</' + key + '>';
  58. }
  59. });
  60. // Close the root
  61. xmlData += '</response>';
  62. response.setContentType('application/xml');
  63. try {
  64. response.base.writer.print(new XML(xmlData));
  65. } catch (e) {
  66. throw new Error(e.message + '\n\r' + e.stack, e.fileName, e.lineNumber);
  67. }
  68. }
  69. /**
  70. * Render a page designer page
  71. * @param {string} pageID - Path to an ISML template
  72. * @param {dw.util.HashMap} aspectAttributes - aspectAttributes to be passed to the PageMgr
  73. * @param {Object} data - Data to be passed
  74. * @param {Object} response - Response object
  75. * @returns {void}
  76. */
  77. function page(pageID, aspectAttributes, data, response) {
  78. if (aspectAttributes && !aspectAttributes.isEmpty()) {
  79. response.base.writer.print(PageMgr.renderPage(pageID, aspectAttributes, JSON.stringify(data)));
  80. } else {
  81. response.base.writer.print(PageMgr.renderPage(pageID, JSON.stringify(data)));
  82. }
  83. }
  84. /**
  85. * Determines what to render
  86. * @param {Object} res - Response object
  87. * @returns {void}
  88. */
  89. function applyRenderings(res) {
  90. if (res.renderings.length) {
  91. res.renderings.forEach(function (element) {
  92. if (element.type === 'render') {
  93. switch (element.subType) {
  94. case 'isml':
  95. template(element.view, res.viewData);
  96. break;
  97. case 'json':
  98. json(res.viewData, res);
  99. break;
  100. case 'xml':
  101. xml(res.viewData, res);
  102. break;
  103. case 'page':
  104. page(element.page, element.aspectAttributes, res.viewData, res);
  105. break;
  106. default:
  107. throw new Error('Cannot render template without name or data');
  108. }
  109. } else if (element.type === 'print') {
  110. res.base.writer.print(element.message);
  111. } else {
  112. throw new Error('Cannot render template without name or data');
  113. }
  114. });
  115. } else {
  116. throw new Error('Cannot render template without name or data');
  117. }
  118. }
  119. module.exports = {
  120. applyRenderings: applyRenderings
  121. };