Permalink
Browse files

Merge branch 'ahem'

  • Loading branch information...
2 parents 8b43915 + abad5be commit bc4af74e62fed6b4613aa56d533af215a1c084c5 Simon Willison committed Mar 7, 2010
View
@@ -1,6 +1,6 @@
var http = require('http'),
sys = require('sys'),
- posix = require('posix'),
+ fs = require('fs'),
url = require('url');
function extname(path) {
@@ -21,8 +21,13 @@ exports.serveFile = function(req, res, filename) {
return;
}
sys.puts("loading " + filename + "...");
- var promise = posix.cat(filename, encoding);
- promise.addCallback(function(data) {
+ fs.readFile(filename, encoding, function (error, data) {
+ if (error) {
+ status = 404;
+ body = '404'
+ sys.puts("Error loading " + filename);
+ return callback();
+ }
body = data;
headers = [
['Content-Type', content_type],
@@ -34,17 +39,11 @@ exports.serveFile = function(req, res, filename) {
sys.puts("static file " + filename + " loaded");
callback();
});
- promise.addErrback(function() {
- status = 404;
- body = '404'
- sys.puts("Error loading " + filename);
- callback();
- });
}
loadResponseData(function() {
res.sendHeader(status, headers);
- res.sendBody(body, encoding);
- res.finish();
+ res.write(body, encoding);
+ res.close();
});
}
@@ -58,8 +57,8 @@ function respond(res, body, content_type, status) {
res.sendHeader(status || 200, {
'Content-Type': content_type + '; charset=utf-8'
});
- res.sendBody(body, 'utf8');
- res.finish();
+ res.write(body, 'utf8');
+ res.close();
}
exports.respond = respond;
@@ -69,17 +68,17 @@ exports.redirect = redirect = function(res, location, status) {
'Content-Type': 'text/html; charset=utf-8',
'Location': location
});
- res.sendBody('Redirecting...');
- res.finish();
+ res.write('Redirecting...');
+ res.close();
}
exports.extractPost = function(req, callback) {
req.setBodyEncoding('utf-8');
var body = '';
- req.addListener('body', function(chunk) {
+ req.addListener('data', function(chunk) {
body += chunk;
});
- req.addListener('complete', function() {
+ req.addListener('end', function() {
callback(http.parseUri('http://fake/?' + body).params);
});
}
View
@@ -2,42 +2,51 @@
/*global require, process, exports, escape */
var sys = require('sys');
-var posix = require('posix');
+var fs = require('fs');
+var template_system = require('./template');
var cache = {};
var template_path = '/tmp';
-function load(name, parse_function, callback) {
+
+// TODO: get_template
+ // should support subdirectories
+
+/*
+ template_loader.load_and_render('template.html', test_context, function(rendered) {
+ dj.respond(res, rendered);
+ });
+*/
+
+var load = exports.load = function (name, callback) {
+ if (!callback) { throw 'loader.load() must be called with a callback'; }
+
if (cache[name] != undefined) {
- if (callback) {
- callback(cache[name]);
- } else {
- return cache[name];
- }
+ callback(false, cache[name]);
} else {
- if (callback) {
- posix.cat(template_path + '/' + name).addCallback(function(s) {
- cache[name] = parse_function(s);
- callback(cache[name]);
- });
- } else {
- var content = posix.cat(template_path + '/' + name).wait();
- cache[name] = parse_function(content);
- return cache[name];
- }
+ fs.readFile(template_path + '/' + name, function (error, s) {
+ if (error) { callback(error); }
+ cache[name] = template_system.parse(s);
+ callback(false, cache[name]);
+ });
}
-}
+};
+exports.load_and_render = function (name, context, callback) {
+ load(name, function (error, template) {
+ if (error) {
+ callback(error);
+ } else {
+ template.render(context, callback);
+ }
+ });
+};
-function flush() {
+exports.flush = function () {
cache = {};
-}
+};
-function set_path(path) {
+exports.set_path = function (path) {
template_path = path;
-}
-
-exports.load = load;
-exports.set_path = set_path;
-exports.flush = flush;
+};
View
@@ -2,12 +2,9 @@
/*global require, process, exports */
var sys = require('sys');
-var utils = require('utils/utils');
-var template_defaults = require('template/template_defaults');
-var template_loader = require('template/loader');
-
-exports.loader = template_loader;
-exports.load = function (name, callback) { return template_loader.load(name, exports.parse, callback); };
+var string_utils = require('../utils/string');
+var html = require('../utils/html');
+var iter = require('../utils/iter');
function normalize(value) {
if (typeof value !== 'string') { return value; }
@@ -31,7 +28,7 @@ function Token(type, contents) {
process.mixin(Token.prototype, {
split_contents: function () {
- return utils.string.smart_split(this.contents);
+ return string_utils.smart_split(this.contents);
}
});
@@ -179,7 +176,7 @@ process.mixin(FilterExpression.prototype, {
var out = this.filter_list.reduce( function (p,c) {
- var filter = template_defaults.filters[c.name];
+ var filter = context.filters[c.name];
var arg;
if (c.arg) {
@@ -199,9 +196,9 @@ process.mixin(FilterExpression.prototype, {
if (safety.must_escape && !safety.is_safe) {
if (typeof out === 'string') {
- return utils.html.escape(out);
+ return html.escape(out);
} else if (out instanceof Array) {
- return out.map( function (o) { return typeof o === 'string' ? utils.html.escape(o) : o; } );
+ return out.map( function (o) { return typeof o === 'string' ? html.escape(o) : o; } );
}
}
return out;
@@ -214,6 +211,10 @@ function Parser(input) {
this.token_list = tokenize(input);
this.indent = 0;
this.blocks = {};
+
+ var defaults = require('./template_defaults');
+ this.tags = defaults.tags;
+ this.nodes = defaults.nodes;
}
function parser_error(e) {
@@ -222,8 +223,10 @@ function parser_error(e) {
function make_nodelist() {
var node_list = [];
- node_list.evaluate = function (context) {
- return this.reduce( function (p, c) { return p + c(context); }, '');
+ node_list.evaluate = function (context, callback) {
+ iter.reduce(this, function (p, c, idx, list, next) {
+ c(context, function (error, result) { next(error, p + result); });
+ }, '', callback);
};
node_list.only_types = function (/*args*/) {
var args = Array.prototype.slice.apply(arguments);
@@ -238,14 +241,12 @@ function make_nodelist() {
process.mixin(Parser.prototype, {
- callbacks: template_defaults.callbacks,
-
parse: function () {
var stoppers = Array.prototype.slice.apply(arguments);
var node_list = make_nodelist();
var token = this.token_list[0];
- var callback = null;
+ var tag = null;
//sys.debug('' + this.indent++ + ':starting parsing with stoppers ' + stoppers.join(', '));
@@ -259,13 +260,13 @@ process.mixin(Parser.prototype, {
//sys.debug('' + this.indent + ': ' + token);
- callback = this.callbacks[token.type];
- if (callback && typeof callback === 'function') {
- node_list.append( callback(this, token), token.type );
+ tag = this.tags[token.type];
+ if (tag && typeof tag === 'function') {
+ node_list.append( tag(this, token), token.type );
} else {
//throw parser_error('Unknown tag: ' + token[0]);
node_list.append(
- template_defaults.nodes.TextNode('[[ UNKNOWN ' + token.type + ' ]]'),
+ this.nodes.TextNode('[[ UNKNOWN ' + token.type + ' ]]'),
'UNKNOWN'
);
}
@@ -300,6 +301,7 @@ function Context(o) {
this.extends = '';
this.blocks = {};
this.autoescaping = true;
+ this.filters = require('./template_defaults').filters;
}
process.mixin(Context.prototype, {
@@ -345,7 +347,7 @@ process.mixin(Context.prototype, {
},
pop: function () {
return this.scope.shift();
- }
+ },
});
@@ -357,27 +359,29 @@ function Template(input) {
}
process.mixin(Template.prototype, {
- render: function (o) {
+ render: function (o, callback) {
+
+ if (!callback) { throw 'template.render() must be called with a callback'; }
var context = (o instanceof Context) ? o : new Context(o || {});
context.extends = '';
- var rendered = this.node_list.evaluate(context);
-
- if (context.extends) {
- var parent_template = exports.load(context.extends);
- rendered = parent_template.render(context);
- }
+ this.node_list.evaluate(context, function (error, rendered) {
+ if (error) { callback(error); }
- return rendered;
+ if (context.extends) {
+ var template_loader = require('./loader');
+ template_loader.load_and_render(context.extends, context, callback);
+ } else {
+ callback(false, rendered);
+ }
+ });
}
});
/********************************************************/
exports.parse = function (input) {
- //var parser = new Parser(input);
- // TODO: Better error handling, this is lame
return new Template(input);
};
@@ -386,6 +390,7 @@ exports.parse = function (input) {
exports.Context = Context;
exports.FilterExpression = FilterExpression;
exports.tokenize = tokenize;
+exports.make_nodelist = make_nodelist;
View
@@ -1,6 +1,6 @@
var sys = require('sys');
-process.mixin(GLOBAL, require('utils/test').dsl);
-process.mixin(GLOBAL, require('template/template'));
+process.mixin(GLOBAL, require('../utils/test').dsl);
+process.mixin(GLOBAL, require('./template'));
testcase('Test tokenizer');
test('sanity test', function () {
@@ -151,15 +151,33 @@ testcase('Context test');
});
testcase('parser')
- test('should parse', function () {
+ test_async('should parse', function (testcontext, complete) {
t = parse('hest');
- assertEquals('hest', t.render());
+ t.render({}, function (error, result) {
+ assertEquals('hest', result, complete);
+ end_async_test( complete );
+ });
});
test('node_list only_types should return only requested typed', function () {
t = parse('{% comment %}hest{% endcomment %}hest{% comment %}laks{% endcomment %}{% hest %}');
assertEquals(['comment','comment'], t.node_list.only_types('comment').map(function(x){return x.type}));
assertEquals(['text','UNKNOWN'], t.node_list.only_types('text', 'UNKNOWN').map(function(x){return x.type}));
});
+testcase('nodelist evaluate');
+ test_async('should work sync', function (testcontext, complete) {
+
+ var context = {};
+ var node_list = make_nodelist();
+ node_list.append( function (context, callback) { callback(false, 'hest'); }, 'test');
+ node_list.append( function (context, callback) { callback(false, 'giraf'); }, 'test');
+ node_list.append( function (context, callback) { callback(false, ' med lang hals'); }, 'test');
+
+ node_list.evaluate( context, function (error, result) {
+ assertEquals('hestgiraf med lang hals', result, complete);
+ end_async_test( complete );
+ });
+ });
+
run();
Oops, something went wrong.

0 comments on commit bc4af74

Please sign in to comment.