Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement import with context #319

Merged
merged 2 commits into from
Dec 11, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions src/compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ var Compiler = Object.extend({
var id = ids[i];
var name = target.value;

this.emitLine('frame.set("' + name + '", ' + id + ', true);');
this.emitLine('frame.set("' + name + '", ' + id + ', true);');

// We are running this for every var, but it's very
// uncommon to assign to multiple vars anyway
Expand Down Expand Up @@ -894,7 +894,9 @@ var Compiler = Object.extend({
this.emitLine(', ' + this.makeCallback(id));
this.addScopeLevel();

this.emitLine(id + '.getExported(' + this.makeCallback(id));
this.emitLine(id + '.getExported(' +
(node.withContext ? 'context.getVariables(), frame.push(), ' : '') +
this.makeCallback(id));
this.addScopeLevel();

frame.set(target, id);
Expand All @@ -915,7 +917,9 @@ var Compiler = Object.extend({
this.emitLine(', ' + this.makeCallback(importedId));
this.addScopeLevel();

this.emitLine(importedId + '.getExported(' + this.makeCallback(importedId));
this.emitLine(importedId + '.getExported(' +
(node.withContext ? 'context.getVariables(), frame.push(), ' : '') +
this.makeCallback(importedId));
this.addScopeLevel();

lib.each(node.names.children, function(nameNode) {
Expand Down
17 changes: 14 additions & 3 deletions src/environment.js
Original file line number Diff line number Diff line change
Expand Up @@ -360,14 +360,24 @@ var Template = Obj.extend({
}.bind(this));
},

getExported: function(cb) {
getExported: function(ctx, frame, cb) {
if (typeof ctx === 'function') {
cb = ctx;
ctx = {};
}

if (typeof frame === 'function') {
cb = frame;
frame = null;
}

this.compile();

// Run the rootRenderFunc to populate the context with exported vars
var context = new Context({}, this.blocks);
var context = new Context(ctx || {}, this.blocks);
this.rootRenderFunc(this.env,
context,
new Frame(),
frame || new Frame(),
runtime,
function() {
cb(null, context.getExported());
Expand All @@ -392,6 +402,7 @@ var Template = Obj.extend({
this.env.extensionsList,
this.path,
this.env.lexerTags);

var func = new Function(source);
props = func();
}
Expand Down
8 changes: 4 additions & 4 deletions src/nodes.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,14 @@ var AsyncEach = For.extend("AsyncEach");
var AsyncAll = For.extend("AsyncAll");
var Macro = Node.extend("Macro", { fields: ['name', 'args', 'body'] });
var Caller = Macro.extend("Caller");
var Import = Node.extend("Import", { fields: ['template', 'target'] });
var Import = Node.extend("Import", { fields: ['template', 'target', 'withContext'] });
var FromImport = Node.extend("FromImport", {
fields: ['template', 'names'],
fields: ['template', 'names', 'withContext'],

init: function(lineno, colno, template, names) {
init: function(lineno, colno, template, names, withContext) {
this.parent(lineno, colno,
template,
names || new NodeList());
names || new NodeList(), withContext);
}
});
var FunCall = Node.extend("FunCall", { fields: ['name', 'args'] });
Expand Down
45 changes: 38 additions & 7 deletions src/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,29 @@ var Parser = Object.extend({
[macroCall]);
},

parseWithContext: function() {
var tok = this.peekToken();

var withContext = null;

if(this.skipSymbol('with')) {
withContext = true;
}
else if(this.skipSymbol('without')) {
withContext = false;
}

if(withContext !== null) {
if(!this.skipSymbol('context')) {
this.fail('parseFrom: expected context after with/without',
tok.lineno,
tok.colno);
}
}

return withContext;
},

parseImport: function() {
var importTok = this.peekToken();
if(!this.skipSymbol('import')) {
Expand All @@ -270,10 +293,15 @@ var Parser = Object.extend({
}

var target = this.parsePrimary();

var withContext = this.parseWithContext();

var node = new nodes.Import(importTok.lineno,
importTok.colno,
template,
target);
target,
withContext);

this.advanceAfterBlockEnd(importTok.value);

return node;
Expand All @@ -286,18 +314,15 @@ var Parser = Object.extend({
}

var template = this.parsePrimary();
var node = new nodes.FromImport(fromTok.lineno,
fromTok.colno,
template,
new nodes.NodeList());

if(!this.skipSymbol('import')) {
this.fail("parseFrom: expected import",
fromTok.lineno,
fromTok.colno);
}

var names = node.names;
var names = new nodes.NodeList(),
withContext;

while(1) {
var nextTok = this.peekToken();
Expand Down Expand Up @@ -343,9 +368,15 @@ var Parser = Object.extend({
else {
names.addChild(name);
}

withContext = this.parseWithContext();
}

return node;
return new nodes.FromImport(fromTok.lineno,
fromTok.colno,
template,
names,
withContext);
},

parseBlock: function() {
Expand Down
28 changes: 28 additions & 0 deletions tests/compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,34 @@
finish(done);
});

it('should import templates with context', function(done) {
equal('{% set bar = "BAR" %}' +
'{% import "import-context.html" as imp with context %}' +
'{{ imp.foo() }}',
"Here's BAR");

equal('{% set bar = "BAR" %}' +
'{% from "import-context.html" import foo with context %}' +
'{{ foo() }}',
"Here's BAR");

finish(done);
});

it('should import templates without context', function(done) {
equal('{% set bar = "BAR" %}' +
'{% import "import-context.html" as imp without context %}' +
'{{ imp.foo() }}',
"Here's ");

equal('{% set bar = "BAR" %}' +
'{% from "import-context.html" import foo without context %}' +
'{{ foo() }}',
"Here's ");

finish(done);
});

it('should inherit templates', function(done) {
equal('{% extends "base.html" %}', 'FooBarBazFizzle');
equal('hola {% extends "base.html" %} hizzle mumble', 'FooBarBazFizzle');
Expand Down
1 change: 1 addition & 0 deletions tests/templates/import-context.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% macro foo() %}Here's {{ bar }}{% endmacro %}