Meteor Spacebars Helpers - Passing another spacebar as helper argument - meteor

I have been trying to pass the spacebar as another spacebar argument like this :
{{helperfunction {{argument}} }}
here the {{argument}} is also coming from another helper function.
Is there any way to achieve this?

You do not need to use the additional {{}}.
lets say that argument is a string and helper function is expecting a string then {{helperFn argument}} is like helperFn(argument). So the single {{ ... }} is sufficient. {{}} using the bracket is like opening a javascript context (kind of) so if arguments is already a defined var that is in scope, there is no need to add additional {{}}.
if you do want to compose blaze helper functions, you can do that by using parens like so {{helperFn1 (helperFn2 argument)}}.
this would be like helperFn1( helperFn2(argument) )
also, if argument is a function, I believe that blaze will call the function and return the result automatically. => {{helperFn argument}} is like helperFn(argument()).
hope that helps a bit.

Related

Meteor/Blaze - Simple string concatenate in parameter

I know how to do this via the more expanded, and probably "proper" method, but I was wondering if there are any simpler ways to do this.
{{> alert message="My message"}}
Basically, I have a template that takes a value message. I want to give it the message Logged in as: samanime, where samanime is whatever the value of currentUser.username.
I know I can do this by creating a helper to concatenate the two parts for me, but is there some way that I can do it without an extra helper? Maybe something like:
{{> alert message="Logged in as: ${currentUser.username}"}}
After playing around with a couple ideas, I think I've come up with a reasonable solution that doesn't violate (too much) the separate of view and logic.
First, to do the actual concatenation, I made a concat helper:
// Takes any number of arguments and returns them concatenated.
UI.registerHelper('concat', function () {
return Array.prototype.slice.call(arguments, 0, -1).join('');
});
Example usage:
{{ concat "a" "b" "c" }}
{{! output: "abc" }}
Then, I made a new block helper, withResult:
Helper:
UI.registerHelper('withResult', function () {
Template._withResult.helpers({result: this.valueOf()});
return Template._withResult;
});
Template:
<template name="_withResult">
{{> UI.contentBlock result=result}}
</template>
Example usage:
{{#withResult concat "a" "b" "c"}}
{{> alert message=result}}
{{/withResult}}
Basically, it takes the result of whatever is the block call (in this case, concat) and puts it in the variable result available to the template.
I think this is a fairly clean and flexible way to not only concat, but also to get other simple multiple-parameter values across. The only negative at this point is it only allows you to create one variable (as each scope puts it in the same spot). However, that can be overcome by having other helpers return objects.
Of course, this is something that you don't want to abuse, as it would blur the clean line that we try to keep between view and logic.

How to create a proxy object in R

I'd like to create a generic proxy mechanism which could intercept any access to the object. Basically for a function it would look like this:
proxy <- function (fn) function (...) {
do.call (fn, list (...));
}
This way I could for example easily add logging. Playing around with assigning formals I can even get it to look like the passed in original function, however this doesn't work for anything that's not a function, is it possible to extend this concept for other types? Some way I could wrap a number and receive a callback anytime it's accessed

Reactively add or remove class

How can you reactively add or remove a class to an element with spacebars?
Also can anyone point me in the direction of the documentation for spacebars format.
Specifically logical functions in the {{#if condition1 && condition2}} style.
Thanks
Currently there are no logical operations allowed in "if" statements, but you can workaround this by providing a custom helper. The easiest way to reactively modify your class would be:
<div class="{{#if isActive}}active{{/if}}"></div>
or just
<div class="{{yieldClass}}"></div>
where yieldClass is some (possibly reactive) helper in your template.
Spacebars currently don't provide a way to perform logical (nor other) functions for arguments.
If you need to make logical operations on your if helper arguments in several places, it is best to define your own custom helper:
UI.registerHelper('and', function(a, b) {
return a && b;
});
{{#if and condition1 condition2}}
...
{{/if}

How to give default alternatives in Handlebars

After going through the docs twice, I gave up and wrote this in a template:
{{#if myVar}}{{myVar}}{{else}}{{myDefaultVar}}{{/if}}
Am I missing some Handlebars built-in feature for this, as it feels like it is going to come up a lot! (I realize I can write my own helper for it, and will do that if Handlebars has nothing built-in.)
Pending some discovery that Handlebars supports this natively, here is the helper I wrote:
Handlebars.registerHelper("P", function(){
for(var i=0;i<arguments.length;++i)if(arguments[i])return arguments[i];
});
So the long {{#if}} becomes this:
{{P myVar myDefaultVar}}
It allows multiple defaults, using whichever comes first, so I might have something like this:
Welcome {{P user.nickname user.fullName "guest"}}!
If the user has given a nickname, use that, otherwise use their full name. If they have given neither, refer to them as "guest".

Is there a way to apply multiple helpers to a template in Handlebars?

I have two Handlebars helpers which I use.
First is timeboundset which takes an array and a datefield and only selects and applies those elements which fall after that datefield.
Second is sortedset which sorts the array first and then uses its elements.
Is there a way I can use both the helpers on the array in html itself and not doing any workaround in Javascript.?
amwmedia commented on GitHub on Oct 7, 2014 that "this appears to have native support using something like:"
{{ helper1 (helper2 text) }}
It does indeed appear to work natively, without the need to register a helper. Note that the helper inside the () braces is executed first, the helper outside last:
{{ executesLast (executesFirst text) }}
There are no plans to support that functionality.
https://github.com/wycats/handlebars.js/issues/304
Although, there's an implementation you could try out if you really want it.

Resources