-
Notifications
You must be signed in to change notification settings - Fork 479
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
Fix inconsistency in resolving dust reference #47
Comments
Something similar to this issue has been causing me headaches. I took a stab at revising getPath to handle cases like this. Code is below. It needs some review from those more familiar with the innards of dust than I am so far plus throwing it against a battery of tests lest it break something. It seems to cure your cases and fix my headaches so I'm hopeful. Code adds two functions and modifies existing getPath. Note: find method is a near duplicate of get but returns pointer to location rather than value in location. I debated. I didn't consolidate them but one could have get call find to reduce code bulk. // Find parent stack level with this key. Returns pointer or undefined if not found. Context.prototype.getPath = function(cur, down) { if (cur && len === 0) return stk.head; // Match a subpath in "down" from current position. Returns final match or undefined. |
From what I understand, get ( walks up the tree, so it is bottom up traversing of the context stack he creates ) while(ctx) { getPath ( is walking down the tree from the "current stack head" )
Hence it fails to find the another inside of the current stack head : { "name" :Larry, "age" : "45"} Instead if it was a block, it would do a "get" and walk up the tree. But the real confusing part is that, using the block # does not make it a new block at that point ( and use the the get ) It is the combination of # and . ( that is not spec'ed out clearly, as to what needs to happen ) so I am open to fixing this abd basically using the solution you propose. |
I'm not sure I agree. I took your example and changed it slightly by adding a simple value as a peer of "person" and "another". var json = { {#person} {#person} Then if I reference {simpleAnother} in the {#person} context, the get will go up the stack and find "simpleAnother". Handlebars has a mechanism to allow accessing structured values from ancestors of the current context. https://github.com/wycats/handlebars.js The original docs for dust say As an alternative, he suggests passing the key as a parameter (e.g. This works but for any but the simplest substructure or with many values it quickly becomes onerous. I keep hitting up against this issue when I do things that add a layer to the context stack because what was a current path ceases to be current and getPath won't find it. Cheers, Rich From: Veena Basavaraj [reply@reply.github.com] I was a little irritated with the inconsistency, but digging deeper, I think agree with his implementation now. From what I understand, get ( walks up the tree, so it is bottom up traversing of the context stack he created ),Context.prototype.get = function(key) { while(ctx) { getPath ( is walking down the tree from the "current stack head" )
Hence it fails to find the another inside of the current stack head : { "name" :Larry, "age" : "45"} Instead if it was a block, it would do a "get" and walk up the tree Reply to this email directly or view it on GitHub: |
thanks for your detailed response. We both seem to agree that the implementation is legit and is according to what he explains:) the difference is basically between when it uses get and when it uses getPath ( a dot operator forces it to be local, walking down the tree ) (function(){dust.register(null,body_0);function body_0(chk,ctx){return chk.section(ctx.getPath(false,["person","in"]),ctx,{"block":body_1},null).write("------------------------");}function body_1(chk,ctx){return chk.reference(ctx.get("simpleAnother"),ctx,"h").reference(ctx.get("name"),ctx,"h").write(", ").reference(ctx.get("age"),ctx,"h").section(ctx.getPath(false,["another","in"]),ctx,{"block":body_2},null);}function body_2(chk,ctx){return chk.write(" // bloc inside the top level person block").reference(ctx.get("name"),ctx,"h").reference(ctx.get("age"),ctx,"h");}return body_0;})(); I am not a big fan of ../ either. But I see your pain, some of us as well have felt the same, where "." has confused us ( since we most often overlook the current stack head ) Our solution : avoid the path and avoid inline params if possible, instead use blocks ( this uses the get( ) method and allows us to access the values upto to the root ) So our resort has been to use the block context whenever we need to walk into or access the data of other nodes in the JSON https://github.com/linkedin/dustjs/wiki/Dust.js-little-less-know-language-constructs If we want to access the projects -> name inside the comments block, all we need to do is create the team->projects block Down side : we have to be careful in making sure that some typos in the JSON or missing data in some cases, does not let dust walk way more than we intended to. Another topic you bring up is the helper : local We do want to create a local scope at times, for creating local contexts ( we create a new context, copy only the required context.get("somekey"), copy the inline params to it ans do a dust.makeBase( newlocalcontext) ) is this what you intended? |
given JSON
Expected : The above should work and output the data within the block. "another"
Observed: It does not output Tommy 44, instead only Larry 45 is shown
Alternatively,
The following works,
why? since another is the top level block in the above example, using the . operator works. Any sub contexts using .operator do not work.
The only way to make the above work is reference a subcontext children is via creating a # context
{/person}
The text was updated successfully, but these errors were encountered: