renderer.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /* renderer.coffee */
  2. (function() {
  3. var ContentTree, Stream, async, extend, fs, mkdirp, path, pump, ref, render, renderView, setImmediate, util;
  4. fs = require('fs');
  5. util = require('util');
  6. async = require('async');
  7. path = require('path');
  8. mkdirp = require('mkdirp');
  9. Stream = require('stream').Stream;
  10. ContentTree = require('./content').ContentTree;
  11. ref = require('./utils'), pump = ref.pump, extend = ref.extend;
  12. if (typeof setImmediate === "undefined" || setImmediate === null) {
  13. setImmediate = process.nextTick;
  14. }
  15. renderView = function(env, content, locals, contents, templates, callback) {
  16. return setImmediate(function() {
  17. var _locals, name, view;
  18. _locals = {
  19. env: env,
  20. contents: contents
  21. };
  22. extend(_locals, locals);
  23. view = content.view;
  24. if (typeof view === 'string') {
  25. name = view;
  26. view = env.views[view];
  27. if (view == null) {
  28. callback(new Error("content '" + content.filename + "' specifies unknown view '" + name + "'"));
  29. return;
  30. }
  31. }
  32. return view.call(content, env, _locals, contents, templates, function(error, result) {
  33. if (error != null) {
  34. error.message = content.filename + ": " + error.message;
  35. }
  36. return callback(error, result);
  37. });
  38. });
  39. };
  40. render = function(env, outputDir, contents, templates, locals, callback) {
  41. /* Render *contents* and *templates* using environment *env* to *outputDir*.
  42. The output directory will be created if it does not exist.
  43. */
  44. var items, renderPlugin;
  45. env.logger.info("rendering tree:\n" + (ContentTree.inspect(contents, 1)) + "\n");
  46. env.logger.verbose("render output directory: " + outputDir);
  47. renderPlugin = function(content, callback) {
  48. /* render *content* plugin, calls *callback* with true if a file is written; otherwise false. */
  49. return renderView(env, content, locals, contents, templates, function(error, result) {
  50. var destination, writeStream;
  51. if (error) {
  52. return callback(error);
  53. } else if (result instanceof Stream || result instanceof Buffer) {
  54. destination = path.join(outputDir, content.filename);
  55. env.logger.verbose("writing content " + content.url + " to " + destination);
  56. mkdirp.sync(path.dirname(destination));
  57. writeStream = fs.createWriteStream(destination);
  58. if (result instanceof Stream) {
  59. return pump(result, writeStream, callback);
  60. } else {
  61. return writeStream.end(result, callback);
  62. }
  63. } else {
  64. env.logger.verbose("skipping " + content.url);
  65. return callback();
  66. }
  67. });
  68. };
  69. items = ContentTree.flatten(contents);
  70. return async.forEachLimit(items, env.config._fileLimit, renderPlugin, callback);
  71. };
  72. /* Exports */
  73. module.exports = {
  74. render: render,
  75. renderView: renderView
  76. };
  77. }).call(this);