indexHandlers.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /* global __dirname */
  2. "use strict";
  3. var _ = require('lodash');
  4. var Mustache = require('mustache');
  5. var path = require('path');
  6. var fs = require('fs');
  7. var chokidar = require('chokidar');
  8. var indexTmplPath = path.normalize(__dirname + '/../html/index.mustache.html');
  9. var indexTpml;
  10. var {
  11. readFilesAsync
  12. } = require('../lib/fsio');
  13. var translator = require('../lib/translator');
  14. var passLog = require('../lib/passLog');
  15. // One-liner for current directory, ignores .dotfiles
  16. chokidar.watch('./html', {ignored: /(^|[\/\\])\../}).on('all', (event, path) => {
  17. // console.log(event, path);
  18. if(path === 'html/index.mustache.html') {
  19. console.log('reload index html');
  20. indexTpml = fs.readFileSync(indexTmplPath).toString();
  21. }
  22. });
  23. module.exports = function(exStore, exDir, testMode) {
  24. function readExampleFiles(repoSlug, exampleSlug, config) {
  25. const exampleDir = exDir + '/' + repoSlug + '/' + exampleSlug;
  26. const libsCssDir = path.normalize(__dirname + '/../css/vendor');
  27. const libsJsDir = path.normalize(__dirname + '/../js/vendor');
  28. const { html, js, css } = config; // libsCss, libsJs
  29. const files = [].concat(html, js, css);
  30. return readFilesAsync(exampleDir, files);
  31. }
  32. function renderIndex(req, withRepo, withExample) {
  33. // Extract repoSlug and exampleSlug from req.params
  34. const { locale, params: { repoSlug, exampleSlug } } = req;
  35. let repo;
  36. let menuExample;
  37. let statusCode;
  38. // Initialize view data
  39. let data = {
  40. menuRepo: exStore.getRepoMenu(),
  41. repoJSON: 'null',
  42. exampleJSON: 'null',
  43. testMode,
  44. testRun: testMode && req.query.testing,
  45. appPath: req.path,
  46. _: translator.getAll(locale)
  47. };
  48. // Fetch example repository if needed
  49. if(withRepo) {
  50. data.repo = exStore.getRepo(repoSlug);
  51. data.repoJSON = JSON.stringify(data.repo);
  52. if(! data.repo) {
  53. // return res.status(404).send('Repo ' + req.params.repoSlug + ' not found');
  54. data.errorMessage = translator.getOne(locale, "repoNotFound", [repoSlug]); //'Repo ' + params.repoSlug + ' not found';
  55. statusCode = 404;
  56. }
  57. else {
  58. data.menuExample = exStore.getExampleMenu(data.repo.path);
  59. data.showControls = true;
  60. }
  61. }
  62. // Fetch example if needed
  63. if(withExample && data.repo) {
  64. data.example = _.find(data.repo.examples, { slug: exampleSlug });
  65. data.exampleJSON = JSON.stringify(data.example);
  66. if(! data.example) {
  67. // return res.status(404).send('Example ' + req.params.repoSlug + '/' + req.params.exampleSlug + ' not found');
  68. data.errorMessage = translator.getOne(locale, "exampleNotFound", [repoSlug, exampleSlug]);
  69. statusCode = 404;
  70. }
  71. else {
  72. data.showEditor = true;
  73. }
  74. }
  75. // Mustache.render(indexTpml, data);
  76. return (
  77. exampleSlug && data.example ?
  78. readExampleFiles(repoSlug, exampleSlug, data.example) : Promise.resolve([])
  79. ).then(files =>
  80. ({ files, filesJSON: JSON.stringify(files) })
  81. )
  82. .then(({ files, filesJSON }) => Object.assign(data, { files, filesJSON }))
  83. .then(passLog('data before rendering, path: ' + req.path))
  84. .then(data => ({
  85. html: Mustache.render(indexTpml, data),
  86. code: statusCode ? statusCode : 200
  87. }));
  88. }
  89. return {
  90. /**
  91. * Extract language header from req
  92. */
  93. getAcceptLanguage: function (req, res, next) {
  94. const acceptLanguageHdr = req.headers["accept-language"];
  95. const re = /[a-z]{2}\-[A-Z]{2}/;
  96. const matches = re.exec(acceptLanguageHdr);
  97. if(matches) {
  98. req.locale = matches[0];
  99. }
  100. next();
  101. },
  102. /**
  103. * Get bare index without repo or examples
  104. */
  105. getIndexBare: function(req, res) {
  106. renderIndex(req)
  107. .then(({ html, code }) => res.send(html));
  108. },
  109. /**
  110. * Get bare index without repo or examples,
  111. * for running tests with QUnit
  112. */
  113. getIndexTest: function(req, res) {
  114. renderIndex(req, false, false)
  115. .then(({ html, code }) => res.send(html));
  116. },
  117. /**
  118. * Get index with repo selected only
  119. */
  120. getIndexRepo: function(req, res) {
  121. renderIndex(req, true)
  122. .then(({ html, code }) => res.status(code).send(html));
  123. // const repo = exStore.getRepo(req.params.repoSlug);
  124. // if(! repo) {
  125. // return res.status(404).send('Repo ' + req.params.repoSlug + ' not found');
  126. // }
  127. // const menuRepo = exStore.getRepoMenu();
  128. // const menuExample = exStore.getExampleMenu(repo.path);
  129. // // const title = 'Home';
  130. // // console.log(menuExample);
  131. // res.send(Mustache.render(indexTpml, {
  132. // // title,
  133. // menuRepo,
  134. // menuExample,
  135. // filesJSON: '[]'
  136. // }));
  137. },
  138. /**
  139. * Get index with selected repo&example
  140. */
  141. getIndexExample: function(req, res) {
  142. renderIndex(req, true, true)
  143. .then(({ html, code }) => res.status(code).send(html));
  144. // console.log('getIndexExample', req.params);
  145. // const repo = exStore.getRepo(req.params.repoSlug);
  146. // if(! repo) {
  147. // return res.status(404).send('Repo ' + req.params.repoSlug + ' not found');
  148. // }
  149. // const menuRepo = exStore.getRepoMenu();
  150. // const menuExample = exStore.getExampleMenu(repo.path);
  151. // const example = _.find(repo.examples, { slug: req.params.exampleSlug });
  152. // if(! example) {
  153. // return res.status(404).send('Example ' + req.params.repoSlug + '/' + req.params.exampleSlug + ' not found');
  154. // }
  155. // // console.log('#1');
  156. // // const title = 'Home';
  157. // // console.log(menuExample);
  158. // const { repoSlug, exampleSlug } = req.params;
  159. // readExampleFiles(repoSlug, exampleSlug, example)
  160. // .then(files => {
  161. // console.log('example files', files);
  162. // res.send(Mustache.render(indexTpml, {
  163. // // title,
  164. // menuRepo,
  165. // menuExample,
  166. // files,
  167. // filesJSON: JSON.stringify(files)
  168. // }));
  169. // });
  170. }
  171. };
  172. };