terraform.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. var fs = require('fs')
  2. var path = require('path')
  3. var stylesheet = require('./stylesheet')
  4. var template = require('./template')
  5. var javascript = require('./javascript')
  6. var helpers = require('./helpers')
  7. var lodash = require('lodash')
  8. /**
  9. * Expose Helpers
  10. *
  11. * We expose the helpers so that other libraries my use them.
  12. * Terraform is much more useful with these helpers.
  13. *
  14. */
  15. exports.helpers = helpers
  16. /**
  17. * Root
  18. *
  19. * This sets the home base directory for the app which affects
  20. * where we begin walking to build the home directory.
  21. *
  22. */
  23. exports.root = function(root, globals){
  24. if(!globals){
  25. globals = {}
  26. }
  27. var LayoutPriorityList = helpers.buildPriorityList("_layout.html")
  28. var layout = helpers.findFirstFile(root, LayoutPriorityList)
  29. var data = helpers.dataTree(root)
  30. var templateObject = { public: data }
  31. for(var key in globals){
  32. templateObject[key] = globals[key]
  33. }
  34. return {
  35. /**
  36. * Render
  37. *
  38. * This is the main method to to render a view. This function is
  39. * responsible to for figuring out the layout to use and sets the
  40. * `current` object.
  41. *
  42. */
  43. render: function(filePath, locals, callback){
  44. // get rid of leading slash (windows)
  45. filePath = filePath.replace(/^\\/g, '')
  46. // locals are optional
  47. if(!callback){
  48. callback = locals
  49. locals = {}
  50. }
  51. /**
  52. * We ignore files that start with underscore
  53. */
  54. if(helpers.shouldIgnore(filePath)) return callback(null, null)
  55. /**
  56. * If template file we need to set current and other locals
  57. */
  58. if(helpers.isTemplate(filePath)) {
  59. /**
  60. * Current
  61. */
  62. locals._ = lodash
  63. locals.current = helpers.getCurrent(filePath)
  64. /**
  65. * Layout Priority:
  66. *
  67. * 1. passed into partial() function.
  68. * 2. in `_data.json` file.
  69. * 3. default layout.
  70. * 4. no layout
  71. */
  72. // 1. check for layout passed in
  73. if(!locals.hasOwnProperty('layout')){
  74. // 2. _data.json layout
  75. // TODO: Change this lookup relative to path.
  76. var templateLocals = helpers.walkData(locals.current.path, data)
  77. if(templateLocals && templateLocals.hasOwnProperty('layout')){
  78. if(templateLocals['layout'] === false){
  79. locals['layout'] = null
  80. } else if(templateLocals['layout'] !== true){
  81. // relative path
  82. var dirname = path.dirname(filePath)
  83. var layoutPriorityList = helpers.buildPriorityList(path.join(dirname, templateLocals['layout'] || ""))
  84. // absolute path (fallback)
  85. layoutPriorityList.push(templateLocals['layout'])
  86. // return first existing file
  87. // TODO: Throw error if null
  88. locals['layout'] = helpers.findFirstFile(root, layoutPriorityList)
  89. }
  90. }
  91. // 3. default _layout file
  92. if(!locals.hasOwnProperty('layout')){
  93. locals['layout'] = helpers.findDefaultLayout(root, filePath)
  94. }
  95. // 4. no layout (do nothing)
  96. }
  97. /**
  98. * TODO: understand again why we are doing this.
  99. */
  100. try{
  101. var error = null
  102. var output = template(root, templateObject).partial(filePath, locals)
  103. }catch(e){
  104. var error = e
  105. var output = null
  106. }finally{
  107. callback(error, output)
  108. }
  109. }else if(helpers.isStylesheet(filePath)){
  110. stylesheet(root, filePath, callback)
  111. }else if(helpers.isJavaScript(filePath)){
  112. javascript(root, filePath, callback)
  113. }else{
  114. callback(null, null)
  115. }
  116. }
  117. }
  118. }