akdubya / dustjs

Asynchronous templates for the browser and node.js
http://akdubya.github.com/dustjs/
MIT License
1.44k stars 124 forks source link

Iterate over properties of an object? Get name of properties? #9

Open ralphholzmann opened 13 years ago

ralphholzmann commented 13 years ago

Hello,

Looking for a way to iterate over an object structured like so:

{
  freenode : 'irc.freenode.net',
  oftc : 'irc.oftc.net',
  ipt : 'irc.ipt.net'
}

I need to output the key names and their values. After combing the docs for quite awhile, I dont see any information on how to do this.

Thanks,

Ralph

akdubya commented 13 years ago

This is a job for contextual helpers.

The template:

{#iter:obj}
  {key}: {value}{~n}
{/iter}

The context:

{
  iter: function(chk, ctx, bodies) {
    var obj = ctx.current();
    for (var k in obj) {
      chk = chk.render(bodies.block, ctx.push({key: k, value: obj[k]}));
    }
    return chk;
  },
  obj: {
    freenode : 'irc.freenode.net',
    oftc : 'irc.oftc.net',
    ipt : 'irc.ipt.net'
  }
}

The output:

freenode: irc.freenode.net
oftc: irc.oftc.net
ipt: irc.ipt.net

Try this out in the dust console. DRY it up by attaching iter (or whatever you want to name it) to your base context as a global helper.

ralphholzmann commented 13 years ago

Thanks for your quick reply! This works great for single level iteration, however the following doesn't work.

Data:

{
networks: {
freenode : {
nick: 'ralphholzmann',
real_name: 'Ralph Holzmann'
},
oftc : {
...
},
ipt : {
...
}
}
}

Template:

{#iter:networks}
{key}
{#iter:value}
{key} : {value}
{/iter}
{/iter}

The second level of key and value do not display.

Aside from the implementation details, I think that this is a feature that should be natively supported by dust, rather than having to define and use a contextual helper.

akdubya commented 13 years ago

To generate arbitrary levels use a recursive inline partial and make sure to assign the helper to the base context (you have to cheat a bit to get it to work in the demo console). Or just write the full object inspection code in the helper.

As for native support, I guess I'm not really seeing how "iterate over a generic object" translates into useful template code. Is there some specific use case you have in mind?

semanticprogrammer commented 13 years ago

I believe you should provide native support for this kind of iteration including support for nested properties. There are many cases when it will be very useful. For example to generate some code from json based model. In fact I'd like to have it right now :) Thank you!

ralphholzmann commented 13 years ago

@semanticprogrammer -- I gave up on dust awhile ago. While its speed and extensibility are to be admired, basic things like this and its interpretation of falsey values (e.g. 0 is not falsey to dust) have driven me to other libs.

semanticprogrammer commented 13 years ago

"@semanticprogrammer -- I gave up on dust awhile ago. While its speed and extensibility are to be admired, basic things like this and its interpretation of falsey values (e.g. 0 is not falsey to dust) have driven me to other libs." Thank you very much for your comment. Please advice me regarding picking up the best alternative to Dust. I'm asking for the advice because I afraid that I will follow your steps if author of Dust will not response to suggestions of his users. By the way I have filled out a new issue with request to create google group to improve user's support.

Almad commented 12 years ago

+1 for this

vybs commented 12 years ago

How often do we have this case? We use it quite a lot and have not seen this as a most pressing concern. logic less templates and arbitrary JSON structure is not the norm IMO.Why does not a helper work? What is the use case for native support.

Almad commented 12 years ago

Of course, it is only matter of convenience and development speed.

vybs commented 12 years ago

:), how does helper not speed it up?

zzen commented 12 years ago

@vybs - in my world, you can iterate over ordered lists or unordered maps just the same… drawing the distinction there seems arbitrary… there is no reason, if you can iterate over an array, why not iterate over an object.

So the answer for "why not helper" is: consistency

aravinda0 commented 12 years ago

Another +1 for this.

mandric commented 12 years ago

+1 for native support

benjajaja commented 11 years ago

+1 IMHO using a helper is putting logic into templating, maps should be "natively" iterable like zzen points out.

pedronasser commented 11 years ago

+1 holy shit this is still not native?

neogeek77 commented 11 years ago

+1 for native support

rashad612 commented 11 years ago

We need something like 'foreach' iteration. I rewrote the previous cheat to be:

dust.helpers.iter = function(chunk, context, bodies, params) {
        var obj = params['for'] || context.current();

        for (var k in obj) {
            chunk = chunk.render(bodies.block, context.push({key: k, value: obj[k]}));
        }
        return chunk;
    };

Template:

{@iter for=obj}
  {key}: {value}{~n}
{/iter}

And our object:

{
  freenode : 'irc.freenode.net',
  oftc : 'irc.oftc.net',
  ipt : 'irc.ipt.net'
}

However, using nested iteration caused double execution time in some case. Any effort to push this forward ?

vybs commented 11 years ago

can we please post this on the helpers repo?

https://github.com/linkedin/dustjs-helpers

rashad612 commented 11 years ago

Done: rashad612/dustjs-helpers@9039130dc060a4bf3e93856601891a7da9047bac