Skip to content
This repository
Browse code

Broke up templating code into separate libs

  • Loading branch information...
commit 0ab798305c775798299ec67fc9f861f973b7c98c 1 parent 003cf6a
Matthew Eernisse authored April 29, 2013
180  lib/template/index.js
@@ -15,14 +15,10 @@
15 15
  * limitations under the License.
16 16
  *
17 17
 */
18  
-var path = require('path')
19  
-  , fs = require('fs')
20  
-  , utils = require('utilities')
21  
-  , Adapter = require('./adapters').Adapter
  18
+var Adapter = require('./adapters').Adapter
22 19
   , Templater
23  
-  , Partial
24  
-  , Layout
25  
-  , cache = {};
  20
+  , Partial = require('./partial').Partial
  21
+  , Layout = require('./layout').Layout;
26 22
 
27 23
 Templater = function () {};
28 24
 
@@ -38,173 +34,3 @@ Templater.prototype = new (function () {
38 34
 })();
39 35
 exports.Templater = Templater;
40 36
 
41  
-Partial = function (templatePath, data, parent) {
42  
-  var self = this;
43  
-  this.id = utils.string.uuid();
44  
-  this.templatePath = templatePath
45  
-  this.data = data;
46  
-  this.parent = parent;
47  
-  this.children = [];
48  
-  this.content = '';
49  
-
50  
-  // Hang a `partial` method on the execution-context for the
51  
-  // template rendering (e.g., will be the EJS global `partial`
52  
-  // function to add sub-templates
53  
-  this.data.partial = function (templatePath, data) {
54  
-    var child = new Partial(templatePath, data, self);
55  
-    self.addChild(child);
56  
-    return '###partial###' + child.id
57  
-  };
58  
-};
59  
-
60  
-Partial.prototype = new (function () {
61  
-
62  
-  this.render = function (cb) {
63  
-    var self = this
64  
-      , templateData = this.getTemplateData()
65  
-      , file = templateData.file
66  
-      , ext = templateData.ext
67  
-      , handleData = function (data) {
68  
-          self.renderSelf(data, ext);
69  
-          self.renderChildren(cb);
70  
-        };
71  
-
72  
-    // Use cached template content if possible
73  
-    if (cache[file]) {
74  
-      handleData(cache[file]);
75  
-    }
76  
-    // Otherwise fetch off disk
77  
-    else {
78  
-      // Get the template from the FS then cache it for subsequent requests
79  
-      fs.readFile(file, 'utf8', function (err, data) {
80  
-        if (err) {
81  
-          throw err;
82  
-        }
83  
-        if (geddy.config.environment != 'development') {
84  
-          cache[file] = data;
85  
-        }
86  
-        handleData(data);
87  
-      });
88  
-    }
89  
-  };
90  
-
91  
-  this.renderSelf = function (templateContent, ext) {
92  
-    var adapter = new Adapter();
93  
-    // Render with appropriate engine
94  
-    adapter.set({engine: ext, template: templateContent});
95  
-    this.content = adapter.render(this.data);
96  
-  };
97  
-
98  
-  this.renderChildren = function (cb) {
99  
-    var self = this
100  
-      , children = this.children
101  
-      , incr = children.length;
102  
-
103  
-    if (children.length) {
104  
-      children.forEach(function (child) {
105  
-        child.render(function (content) {
106  
-          self.content = self.content.replace(
107  
-              '###partial###' + child.id, content);
108  
-          incr--;
109  
-          if (!incr) {
110  
-            cb(self.content);
111  
-          }
112  
-        });
113  
-      });
114  
-    }
115  
-    else {
116  
-      cb(this.content);
117  
-    }
118  
-
119  
-  };
120  
-
121  
-  this.getTemplateData = function () {
122  
-    var dirs = []
123  
-      , dir
124  
-      , key
125  
-      , templatePath = this.templatePath
126  
-      , templateData;
127  
-
128  
-    // Look for an exact match
129  
-    templateData = geddy.templateRegistry[templatePath];
130  
-
131  
-    // No exact match, try with some directory prefixes
132  
-    if (!templateData) {
133  
-      // Loop through dirs until a registered template path is found
134  
-      // Note: Template paths are gathered at init so we don't have to
135  
-      // touch the FS when looking for templates
136  
-
137  
-      // If this is a child partial, then look in the parent's directory
138  
-      if (this.parent) {
139  
-        dirs.unshift(path.dirname(this.parent.templatePath));
140  
-      }
141  
-
142  
-      // Any local template directory
143  
-      dirs.unshift(path.dirname(templatePath));
144  
-
145  
-      // Last resort; look in the base views directory
146  
-      dirs.unshift(path.normalize('app/views'));
147  
-
148  
-
149  
-      for (var i = 0, ii = dirs.length; i < ii; i++) {
150  
-        dir = dirs[i];
151  
-        // Not full path (No extension(s))
152  
-        key = path.normalize(path.join(dir, templatePath));
153  
-
154  
-        templateData = geddy.templateRegistry[key];
155  
-        if (templateData) {
156  
-          break;
157  
-        }
158  
-      }
159  
-    }
160  
-
161  
-    // Still no joy
162  
-    if (!templateData) {
163  
-      // Is this a Layout?
164  
-      if (this instanceof Layout) {
165  
-        // Try to use the default application layout
166  
-        key = path.normalize('app/views/layouts/application');
167  
-        templateData = geddy.templateRegistry[key];
168  
-        // If they've removed the default layout for some reason
169  
-        if (!templateData) {
170  
-          throw new geddy.errors.InternalServerError('Layout template "' +
171  
-                templatePath + '" not found in ' +
172  
-                geddy.utils.array.humanize(dirs));
173  
-        }
174  
-      }
175  
-      // If it's a normal Partial then it doesn't exist, boom
176  
-      else {
177  
-        throw new geddy.errors.InternalServerError('Partial template "' +
178  
-              templatePath + '" not found in ' +
179  
-              geddy.utils.array.humanize(dirs));
180  
-      }
181  
-    }
182  
-
183  
-    return templateData || null;
184  
-  };
185  
-
186  
-  this.addChild = function (child) {
187  
-    this.children.push(child);
188  
-  };
189  
-
190  
-})();
191  
-
192  
-// Subclass of Partial
193  
-Layout = function (layoutPath, templatePath, data) {
194  
-  var self = this;
195  
-  // Call the ctor on 'this' -- the the layoutPath will be our
196  
-  // templatePath
197  
-  Partial.call(this, layoutPath, data, null);
198  
-
199  
-  // `yield` is just a special case of `partial` using the template-path
200  
-  // that the layout wraps -- just hard-code the path and pass along
201  
-  // the same data
202  
-  this.data.yield = function () {
203  
-    return self.data.partial(templatePath, data);
204  
-  };
205  
-};
206  
-
207  
-Layout.prototype = Object.create(Partial.prototype);
208  
-Layout.prototype.constructor = Layout;
209  
-
210  
-exports.Templater = Templater;
22  lib/template/layout.js
... ...
@@ -0,0 +1,22 @@
  1
+var Layout
  2
+  , Partial = require('./partial').Partial;
  3
+
  4
+// Subclass of Partial
  5
+Layout = function (layoutPath, templatePath, data) {
  6
+  var self = this;
  7
+  // Call the ctor on 'this' -- the the layoutPath will be our
  8
+  // templatePath
  9
+  Partial.call(this, layoutPath, data, null);
  10
+
  11
+  // `yield` is just a special case of `partial` using the template-path
  12
+  // that the layout wraps -- just hard-code the path and pass along
  13
+  // the same data
  14
+  this.data.yield = function () {
  15
+    return self.data.partial(templatePath, data);
  16
+  };
  17
+};
  18
+
  19
+Layout.prototype = Object.create(Partial.prototype);
  20
+Layout.prototype.constructor = Layout;
  21
+
  22
+exports.Layout = Layout;
165  lib/template/partial.js
... ...
@@ -0,0 +1,165 @@
  1
+var Partial
  2
+  , Layout
  3
+  , Adapter = require('./adapters').Adapter
  4
+  , path = require('path')
  5
+  , fs = require('fs')
  6
+  , utils = require('utilities')
  7
+  , cache = {};
  8
+
  9
+Partial = function (templatePath, data, parent) {
  10
+  var self = this;
  11
+  this.id = utils.string.uuid();
  12
+  this.templatePath = templatePath
  13
+  this.data = data;
  14
+  this.parent = parent;
  15
+  this.children = [];
  16
+  this.content = '';
  17
+
  18
+  // Hang a `partial` method on the execution-context for the
  19
+  // template rendering (e.g., will be the EJS global `partial`
  20
+  // function to add sub-templates
  21
+  this.data.partial = function (templatePath, data) {
  22
+    var child = new Partial(templatePath, data, self);
  23
+    self.addChild(child);
  24
+    return '###partial###' + child.id
  25
+  };
  26
+};
  27
+
  28
+Partial.prototype = new (function () {
  29
+
  30
+  this.getTemplateData = function () {
  31
+    var dirs = []
  32
+      , dir
  33
+      , key
  34
+      , templatePath = this.templatePath
  35
+      , templateData;
  36
+
  37
+    // Look for an exact match
  38
+    templateData = geddy.templateRegistry[templatePath];
  39
+
  40
+    // No exact match, try with some directory prefixes
  41
+    if (!templateData) {
  42
+      // Loop through dirs until a registered template path is found
  43
+      // Note: Template paths are gathered at init so we don't have to
  44
+      // touch the FS when looking for templates
  45
+
  46
+      // If this is a child partial, then look in the parent's directory
  47
+      if (this.parent) {
  48
+        dirs.unshift(path.dirname(this.parent.templatePath));
  49
+      }
  50
+
  51
+      // Any local template directory
  52
+      dirs.unshift(path.dirname(templatePath));
  53
+
  54
+      // Last resort; look in the base views directory
  55
+      dirs.unshift(path.normalize('app/views'));
  56
+
  57
+
  58
+      for (var i = 0, ii = dirs.length; i < ii; i++) {
  59
+        dir = dirs[i];
  60
+        // Not full path (No extension(s))
  61
+        key = path.normalize(path.join(dir, templatePath));
  62
+
  63
+        templateData = geddy.templateRegistry[key];
  64
+        if (templateData) {
  65
+          break;
  66
+        }
  67
+      }
  68
+    }
  69
+
  70
+    // Still no joy
  71
+    if (!templateData) {
  72
+      // Is this a Layout?
  73
+      if (this instanceof Layout) {
  74
+        // Try to use the default application layout
  75
+        key = path.normalize('app/views/layouts/application');
  76
+        templateData = geddy.templateRegistry[key];
  77
+        // If they've removed the default layout for some reason
  78
+        if (!templateData) {
  79
+          throw new geddy.errors.InternalServerError('Layout template "' +
  80
+                templatePath + '" not found in ' +
  81
+                geddy.utils.array.humanize(dirs));
  82
+        }
  83
+      }
  84
+      // If it's a normal Partial then it doesn't exist, boom
  85
+      else {
  86
+        throw new geddy.errors.InternalServerError('Partial template "' +
  87
+              templatePath + '" not found in ' +
  88
+              geddy.utils.array.humanize(dirs));
  89
+      }
  90
+    }
  91
+
  92
+    return templateData || null;
  93
+  };
  94
+
  95
+  this.render = function (cb) {
  96
+    var self = this
  97
+      , templateData = this.getTemplateData()
  98
+      , file = templateData.file
  99
+      , ext = templateData.ext
  100
+      , handleData = function (data) {
  101
+          self.renderSelf(data, ext);
  102
+          self.renderChildren(cb);
  103
+        };
  104
+
  105
+    // Use cached template content if possible
  106
+    if (cache[file]) {
  107
+      handleData(cache[file]);
  108
+    }
  109
+    // Otherwise fetch off disk
  110
+    else {
  111
+      // Get the template from the FS then cache it for subsequent requests
  112
+      fs.readFile(file, 'utf8', function (err, data) {
  113
+        if (err) {
  114
+          throw err;
  115
+        }
  116
+        if (geddy.config.environment != 'development') {
  117
+          cache[file] = data;
  118
+        }
  119
+        handleData(data);
  120
+      });
  121
+    }
  122
+  };
  123
+
  124
+  this.renderSelf = function (templateContent, ext) {
  125
+    var adapter = new Adapter();
  126
+    // Render with appropriate engine
  127
+    adapter.set({engine: ext, template: templateContent});
  128
+    this.content = adapter.render(this.data);
  129
+  };
  130
+
  131
+  this.renderChildren = function (cb) {
  132
+    var self = this
  133
+      , children = this.children
  134
+      , incr = children.length;
  135
+
  136
+    if (children.length) {
  137
+      children.forEach(function (child) {
  138
+        child.render(function (content) {
  139
+          self.content = self.content.replace(
  140
+              '###partial###' + child.id, content);
  141
+          incr--;
  142
+          if (!incr) {
  143
+            cb(self.content);
  144
+          }
  145
+        });
  146
+      });
  147
+    }
  148
+    else {
  149
+      cb(this.content);
  150
+    }
  151
+
  152
+  };
  153
+
  154
+  this.addChild = function (child) {
  155
+    this.children.push(child);
  156
+  };
  157
+
  158
+})();
  159
+
  160
+exports.Partial = Partial;
  161
+
  162
+// Layout is a subclass of Partial, depends on it
  163
+// being defined
  164
+Layout = require('./layout').Layout;
  165
+

0 notes on commit 0ab7983

Please sign in to comment.
Something went wrong with that request. Please try again.