dustjs icon indicating copy to clipboard operation
dustjs copied to clipboard

Proposal for additional $ properties

Open claviska opened this issue 9 years ago • 8 comments

I don't want to submit a PR without some feedback about this first. Essentially, I'd like to add a handful of very useful $ properties.

Currently, we have $idx and $len. I'd like to add the following:

  • $first - equals true during the first iteration, false otherwise
  • $last - equals true during the last iteration, false otherwise
  • $count - equals the current count of the iteration (1-based index)

I've come across a number of circumstances where the corresponding helpers are too verbose or don't work. Perhaps the biggest use case is being able to use the proposed properties with comparison helpers. Some examples:

{?$first}...{/$first}               <-- first item only
{^$first}...{/$first}               <-- everything except the first item

{?$last}...{/$last}                 <-- last item only
{^$last}...{/$last}                 <-- everything except the last item

{@eq key=$count value=4}{/eq}       <-- a specific item

I realize Dust aims to use "less logic", but sometimes we don't have complete control over datasets (or we have to go out of our way to adapt them). These special properties add a huge convenience to Dust templates.

Here is a simple modification to this section of the code that adds the propsed properties:

if (len > 0) {
  head = context.stack && context.stack.head || {};
  head.$len = len;
  for (i = 0; i < len; i++) {
    head.$first = i === 0;
    head.$last = i === len - 1;
    head.$count = i + 1;
    head.$idx = i;
    chunk = body(chunk, context.push(elem[i], i, len));
  }
  head.$idx = undefined;
  head.$len = undefined;
  head.$first = undefined;
  head.$last = undefined;
  head.$count = undefined;
  return chunk;
} else if (skip) {
  return skip(this, context);
}

I haven't done extensive testing, but it's a pretty straight-forward addition that seems to work well. (Of course, it works properly in nested loops as well.)

FWIW, I'd also suggest the aliases $index and $length for consistency and legibility, but that's another discussion.

Interested to hear the developer's and the community's thoughts on this.

Re:

  • #720
  • https://github.com/linkedin/dustjs-helpers/issues/15
  • https://github.com/linkedin/dustjs-helpers/issues/58
  • http://stackoverflow.com/questions/14781217/in-dust-js-can-the-inital-value-of-idx-not-be-zero-based

claviska avatar Jan 29 '17 16:01 claviska

I would suggest not placing them on head itself. See #654.

I wish there were a slightly better way to bundle these metadata together but $ props seems fine. I'm a fan. @jimmyhchan?

sethkinast avatar Jan 29 '17 16:01 sethkinast

Makes sense. If this were to proceed, would you recommend keeping them on the head for consistency in 2.x until #654 is merged?

claviska avatar Jan 29 '17 16:01 claviska

Your change would supercede #654 anyways, and the next Dust release will likely be the one where we want to break compat, so it's a good time :)

sethkinast avatar Jan 31 '17 23:01 sethkinast

Awesome. I think these properties will be well-received and are fairly straightforward, but did you want to wait a bit for additional feedback before I submit a proper PR with tests?

claviska avatar Feb 01 '17 00:02 claviska

I think the only one I'm ambivalent on is $count, it's a little ambiguous (but I get the point). @jimmyhchan ?

sethkinast avatar Feb 01 '17 00:02 sethkinast

I've seen other systems use something like $index1 but it feels a bit less elegant. I decided on $count because that's how you would "count" each iteration verbally, but definitely open to an alternative name. 🙂

claviska avatar Feb 01 '17 00:02 claviska

definitely useful. Seems i already said my thoughts in the comments in #654. Ideally for me, we fix how this is implemented so that we can

  1. change the implementation underneath without causing breaking changes (It being a writable and on the context directly is awful. Folks relying on this as a "free" variable will break)
  2. allow this to be extensible without changing the core. Similar to helpers. (depends on 1)

That said we could just dump this in and make everyone happy and accept the bit of tech debt. (not oppose to that)

jimmyhchan avatar Feb 01 '17 04:02 jimmyhchan

@jimmyhchan Making properties extensible will be incredible, especially if defaults can be overwritten with custom props (like helpers and filters). Great idea. 👍

claviska avatar Feb 01 '17 15:02 claviska