Multiple Spacebar Conditional Operators
Asked Answered
W

2

5

Is there a way to shorten

{{#if arg1}}
    {{#if arg2}}
        //stuff
    {{/if}}
{{/if}}

to just a single if?

{{#if arg1 arg2}}
{{#if arg1 && arg2}}

Both of the above don't seem to work.

Worden answered 4/11, 2014 at 21:17 Comment(1)
I discovered I can use UI.registerHelper(), however I am unsure how to configure this to take in any number of arguements. (Arrays do not seem to work, have yet to try maps)Worden
T
8

Spacebars continues the philosophy of Mustache and Handlebars being logic-less template languages. This is why even simple logic is best placed in the controller rather than in the template.

You can, however, define a custom block helper that performs a logical and.

<template name="ifand">
  {{#if arg1}}
    {{#if arg2}}
      {{> Template.contentBlock}}
    {{else}}
      {{> Template.elseBlock}}
    {{/if}}
  {{else}}
    {{> Template.elseBlock}}
  {{/if}}
</template>

Call as:

{{#ifand arg1="foo" arg2="bar"}}
  // stuff
{{/ifand}}

You can also learn more about passing variables into templates.

For the general case (and among an arbitrary number of arguments), you'll want to register a global template helper:

Template.registerHelper('and', function () {
  var args = Array.prototype.slice.call(arguments, 0, -1);  // exclude key=value args
  var parameters = arguments[arguments.length - 1];  // key: value arguments

  return _.every(args, function (arg) {
    return !!arg;
  });

});

Call as:

{{#if and 1 "foo" 3 'bar' param="test"}}
  True
{{else}}
  False
{{/if}}
Thoroughfare answered 4/11, 2014 at 21:35 Comment(4)
I know how to pass variables into templates, what worries me about this approach is it isn't capable of handling X arguements. I need a number of different templates to perform essentially the same task. Being able to define my own helpers feels like the correct route to go, but I do not understand how passing variables into the helper works, unless it has the same problem of only being able to handle a single variable.Worden
Can you not define Template successfully in the lib folder? If not, where is the best place to put global Template helper definitions?Worden
I'd put them in /client/lib. Template should be defined there.Thoroughfare
That's a good idea. I'll make a note of that for my standards. Thanks for all your help good sir.Worden
W
1

While within a template, you are able to use the this object to reference arguments passed in, which lets me avoid having to use multiple #if arguements in most of the cases I need them in.

Template.myTemplate.created = function() {
    if(this.data.arg1 && this.data.arg2) {
        //do JS setup here
    }
}

Additionally, helpers can be specified using

Template.registerHelper('exists', function() {
    if(this.data.arg1 && this.data.arg2) {
        return true
    }
}

and you execute the above helper as such

{{#if exists}}
    //stuff
{{/if}}

{{> myTemplate arg1 arg2}}

I just stumbled on this by accident but this is a HUGE find for me.

Worden answered 4/11, 2014 at 21:56 Comment(5)
I believe UI.registerHelper is, being deprecated. Please check my updated answer.Thoroughfare
I tried using Template.registerHelper, and it kept telling me that Template was undefined. This is odd. If this is the case, I need to figure out why it isn't working for me and update this accordingly.Worden
Updated this to reflect your information so I don't spread information. Please see my comment on your answer though, as UI exists during lib definition but Template does not and I feel like lib is where I should be defining my global helpers.Worden
I tried this out and it didn't work for me. I didn't even see a data property off of the .this context. I tried this for example {{> myTemplate "country" "label for country" "true" "another string with spaces" true}}. Then Template.registerHelper('exists', function ([no parameters?]) { if (this.data.arg1) { return true } }); There is not this.data, what is the arg1 in my case? How do I refer to "country" for example? I looked at the locals in debug, there is no "country". Thanks for this tip by the way. I hope it works as I usually have to build a dummy helper that's just a pass-throughPontefract
I don't know what .data isn't being exposed to you (and I assume is why there are no args in that function call, because you reference the args through .data). Are you using Meteor 1.0X?Worden

© 2022 - 2024 — McMap. All rights reserved.