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

join helper #478

Closed
rbucker opened this issue Apr 4, 2013 · 4 comments
Closed

join helper #478

rbucker opened this issue Apr 4, 2013 · 4 comments

Comments

@rbucker
Copy link

rbucker commented Apr 4, 2013

Yes, keep it simple and stupid. I get it. But so far the use-cases have been addressing HTML as the final output. I have been using HBS to refactor my JSON into different JSON and when iterating over an array there is no way to join or separate the groups in the list.

I suppose they could be treated as partials but I also want to keep the template documents as simple as possible.

@kpdecker
Copy link
Collaborator

kpdecker commented Apr 6, 2013

I'm not sure what this is requesting. Can you provide an example of the API you're thinking?

Niether here nor there but is handlebars the best solution for JSON output? It seems like there is more control using libraries such as JSON.stringify to output JSON.

@rbucker
Copy link
Author

rbucker commented Apr 6, 2013

There have been several similar requests. Each has been denied but for good reason, however, the use-case was all wrong. I do not favor any of the solutions but {{#each sep=','}} or {{#join 'sep'}} or some variation would be fine.

handlebarsjs and mustache are ideally suited for any document where the attributes are in pairs.

<ul>
    {{#each data}}
    <li>{{somevar}}</li>
    {{/each}}
</ul>

however, it's impossible to generate a JSON document because one needs the ',' (comma)

{
    "data":[
    {{#each data}}
        { "somevar":{{somevar}} }
    {{/each}}
    ]
}

You have asked why not use JSON.stringify? The container object that I'm using (a) has more data than I want to transcode/format (b) some of the field names are changed (c) when adding an abstraction layer between the REST server and the REST service there is always a little transcoding, breadcrumbing that is performed. (d) when the external REST layer is versioned differently than the internal container object. (e) I hate the idea of having to write code that could be templated to move data from one object to another just to stringify it.

If there were a #join or an #each with a sep then I am in DRY heaven.

I hope this explains it well enough for a call to action. Thank you for at least humoring me.

I suppose a helper function might work but I do not know for certain as I am not familiar enough with the source. The helper functions I have seen so far have been trivial and only handle the simplest cases were there is a field and a value. I'm not certain it would do nested or semi-partials (ifthat's the correct terms)

I know you do not want to complicate the template's DSL and I strongly agree, however, there are some interesting add-ons for loops in jinga2. #first, #last and others.

Thanks again.

@kpdecker
Copy link
Collaborator

kpdecker commented Apr 6, 2013

Gotcha.

For that specific use case I would go for something like this (using underscore's map to simplify the code):

Handlebars.registerHelper('join', function(context, options) {
  var fn = options.fn;

  return _.map(context, function(value, key) {
    return fn(value, {data: options.data});
  });.join(options.hash.sep);
});

Which would be used like this

{
    "data":[
    {{#join data sep=","}}
        { "somevar":{{somevar}} }
    {{/join}}
    ]
}

I've opened #483 to expand on the first and last detection you mentioned in your last comment.

@kpdecker kpdecker closed this as completed Apr 6, 2013
@rbucker
Copy link
Author

rbucker commented Apr 7, 2013

There was a bug in your helper. Nothing serious, just an extra semi(just before the .join):

Handlebars.registerHelper('join', function(context, options) {
  var fn = options.fn;

  return _.map(context, function(value, key) {
    return fn(value, {data: options.data});
  }).join(options.hash.sep);
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants