Closed carchrae closed 11 years ago
See https://github.com/linkedin/dustjs/pull/174#issuecomment-15903945. If Julian completes what the suggests dealing with in this comment, then I think objects in global will then work
thanks for directing me to that PR. i did not realize that the . notation was not working in regular contexts either - although it is clear by looking at the code i linked to above.
so, the above code fragment should be applied to https://github.com/linkedin/dustjs/blob/master/lib/dust.js#L146 as well:
Context.prototype.get = function(key) {
var ctx = this.stack, value;
while(ctx) {
if (ctx.isObject) {
value = ctx.head[key];
if (!(value === undefined)) {
return value;
}
}
ctx = ctx.tail;
}
return this.global ? this.global[key] : undefined;
};
becomes
Context.prototype.get = function(key) {
var ctx = this.stack, value;
while(ctx) {
if (ctx.isObject) {
value = getDotPath(ctx.head,key);
if (!(value === undefined)) {
return value;
}
}
ctx = ctx.tail;
}
return this.global ? getDotPath(this.global,key) : undefined;
};
where getDotPath is the code i posted above
and sure, you might split the key before the ctx stack search for performance.
also, it is arguable if it should stop if it finds a partial match (not complete path) in the ctx stack search. eg, if the current context has { a : { b : 2 } } and a parent context has { a : { c : 'here it is' } } and you are looking for {a.c}.
the code in the PR seems to work well. btw, please give feedback on the style of adding the helper fuction dotGet - is this the correct way to add it, or should it be part of the prototype? (function does not need this, so adding to prototype seemed wrong)
while i have a working fix to this that passes all tests, i think the solution to this should be in the compiler where it should detect a path - as it does in a scope context reference. (edit: i'm actually a bit confused why this happened at all - perhaps the bug i saw with a global {?foo.bar} is actually a bug elsewhere that did not detect the path correctly!)
A reference like {#arr} {a.b} {/obj} may work if arr contains a.b at runtime or may need to climb up the stack if it does not. How can the compiler help?
In the case of a context reference, the compiler should generate "ctx.getPath" when there is a path (eg, "this.is.a.path". For some reason, it did not when I accessed a global, I think when passed as a parameter - I'll see if I can make this case appear again - clearly it should be a test case.
On Mon, Jun 3, 2013 at 3:13 PM, Richard Ragan notifications@github.comwrote:
A reference like {#arr} {a.b} {/obj} may work if arr contains a.b at runtime or may need to climb up the stack if it does not. How can the compiler help?
— Reply to this email directly or view it on GitHubhttps://github.com/linkedin/dustjs/issues/270#issuecomment-18876678 .
update: this description is now out of date. the issue is how Context.getPath searches through context.
update2: if you want to use this right now, include this gist after including dust.js https://gist.github.com/carchrae/5825054
global variable access does not support objects well because it uses globals[key] to retrieve the value. See: https://github.com/linkedin/dustjs/blob/master/lib/dust.js#L153
this leads to confusing (to developer) behavior - and is inconsistent with the behavior of local context variables (which can use . to access fields.)
for example, if i store a global "foo"={ bar : 123 } and then try to access it in a template, as {foo.bar} it is undefined. "foo" exists but cannot be used with expressions like {?foo.bar} and so on.
my suggestion is you roll out the key access. so, something like