Search code examples
dust.js

Is there a way to do logical OR between two {@eq} conditionals?


I am looking for a way to do logical OR between two {@eq} conditionals. Can I do it in some straightforward way?

For illustration, consider example below. I am iterating over result array. If grp argument is equal to all, I don't want to filter what goes to the page. If it is not equal to all, then I want to filter the array elements by group property being equal to grp. The condition would be expressed as (grp == "all" || group == grp) in JS. Currently, without any way to do OR between the two conditions, I have to repeat the BODY of the loop -- going against the DRY principle.

{#result grp=grp}
  {@eq key=grp value="all"}
    BODY
  {:else}
    {@eq key=group value=grp}
      BODY
    {/eq}
  {/eq}
{/result}

Solution

  • The special {@any} helper allows you to express logical OR. (There is also a {@none} helper for logical NAND.)

    {#result grp=grp}
      {@select}
        {@eq key=grp value="all"/}
        {@eq key=group value=grp/}
        {@any}BODY{/any}
      {/select}
    {/result}
    

    If you need to do something more complex than that-- for example, if BODY is dependent on the value of grp and group-- you can always write a custom Dust helper to move your logic into Javascript. Here's a short example of what that would look like, and you can read further in the documentation on context helpers.

    {
      "filter": function(chunk, context, bodies, params) {
        var group = context.resolve(params.group);
        var grp = context.resolve(params.grp);
    
        if (grp == "all" || group == grp) {
          chunk = chunk.render(bodies.block, context.push({
            somethingNewBasedOff: "the value of group and grp"
          }));
        }
    
        return chunk;
      }
    }
    

    And then you'd use it like:

    {#result grp=grp}
      {#filter group=group grp=grp}
        The filter test passed. The new data I added to the context is {somethingNewBasedOff}
      {/filter}
    {/result}