Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added Blade middleware for client-side templates (solves issue #3)

Updated runtime to work nicely with middleware (solves issue #2)
Remove try, catch block from runtime
Added .gitignore to ignore node_modules
  • Loading branch information...
commit 050233a65595b237da303421dd6effcc0ea40ac4 1 parent cf9f622
@bminer authored
Showing with 64 additions and 15 deletions.
  1. +1 −0  .gitignore
  2. +42 −1 lib/blade.js
  3. +21 −14 lib/runtime.js
View
1  .gitignore
@@ -0,0 +1 @@
+/node_modules
View
43 lib/blade.js
@@ -1,10 +1,12 @@
var fs = require('fs'),
+ path = require('path'),
Compiler = require('./compiler');
exports.compile = compile;
exports.compileFile = compileFile;
exports.Compiler = Compiler;
exports.renderFile = exports.__express = renderFile;
+exports.middleware = middleware;
//Cache of compiled template functions
var cache = {};
@@ -30,6 +32,7 @@ function compile(string, options, cb) {
}
function compileFile(filename, options, cb) {
+ filename = path.normalize(filename);
if(typeof options == "function")
cb = options, options = {};
options.filename = filename;
@@ -47,4 +50,42 @@ function renderFile(filename, options, cb) {
if(err) return cb(err);
tmpl(options, cb);
});
-}
+}
+
+/* Provides a nice Express middleware for compiling client-side templates
+ and delivering them to the client. Weak caching is used by default.
+*/
+function middleware(sourcePath, options) {
+ options = options || {};
+ options.mount = options.mount || '/views/';
+ if(options.clientNamespace == null)
+ options.clientNamespace = "blade.templates";
+ if(options.compileOptions == null)
+ options.compileOptions = {
+ 'cache': process.env.NODE_ENV == "production",
+ 'minify': process.env.NODE_ENV == "production",
+ 'includeSource': process.env.NODE_ENV == "development"
+ };
+ if(options.clientCache == null)
+ options.clientCache = process.env.NODE_ENV == "production";
+ var cache = {}; //key=filename, value=file last modified timestamp
+ return function(req, res, next) {
+ if(req.url.substr(0, options.mount.length) == options.mount)
+ {
+ var filename = req.url.substr(options.mount.length);
+ if(!options.compileOptions.cache && req.headers['if-modified-since'])
+ {
+ //Check cache
+ }
+ compileFile(sourcePath + "/" + filename, options.compileOptions, function(err, tmpl) {
+ if(err) return next(err);
+ res.type('application/javascript');
+ res.send((options.clientCache ? "blade.cachedViews[" + JSON.stringify(filename) + "]=" : "") +
+ options.clientNamespace + "[" + JSON.stringify(filename) + "]=" +
+ tmpl.toString() + "; if(blade.cb[" + JSON.stringify(filename) +
+ "]) blade.cb[" + JSON.stringify(filename) + "](" + options.clientNamespace + ");");
+ });
+ }
+ else next();
+ };
+}
View
35 lib/runtime.js
@@ -2,7 +2,7 @@
var runtime = exports || {};
var cachedViews = {};
if(runtime.client = typeof window != "undefined")
- window.blade = {'runtime': runtime, 'cachedViews': cachedViews};
+ window.blade = {'runtime': runtime, 'cachedViews': cachedViews, 'cb': {}};
runtime.escape = function(str) {
return new String(str)
@@ -31,15 +31,28 @@
}
}
- /* Load the template from a file, optionally store in cache
- Default behavior in Node.JS is to compile the file using Blade,
- caching it, as needed. The client should cache the view if
- `compileOptions.cache` is set to `true`. */
+ /* Load the template from a file
+ Default behavior in Node.JS is to compile the file using Blade.
+ Default behavior in browser is to load async using a script tag. */
runtime.loadTemplate = function(filename, compileOptions, cb) {
if(runtime.client)
{
- //TODO: Load client template
- cb(new Error("Client-side template loading is not yet implemented.") );
+ var st = document.createElement('script');
+ st.type = 'application/javascript';
+ st.async = true;
+ st.src = '/views/' + filename;
+ var s = document.getElementsByTagName('script')[0];
+ s.parentNode.insertBefore(st, s);
+ var timer = setTimeout(function() {
+ delete blade.cb[filename];
+ cb(new Error("Timeout Error: Blade Template [" + filename +
+ "] could not be loaded.") );
+ }, 15000);
+ blade.cb[filename] = function(ns) {
+ clearTimeout(timer);
+ delete blade.cb[filename];
+ cb(null, ns[filename]);
+ };
}
else
{
@@ -103,13 +116,7 @@
else
runtime.loadTemplate(filename, runtime.compileOptions, function(err, tmpl) {
if(err) return cb(err);
- try {
- tmpl(info.locals, runtime, includeDone);
- }
- catch(e) {
- console.log("Caught");
- throw e;
- }
+ tmpl(info.locals, runtime, includeDone);
});
}
Please sign in to comment.
Something went wrong with that request. Please try again.