Im studying the book Meteor in action, in the book authors use html/js, but i prefer jade/coffee. I've met some troubles with this piece of code:
<template name="templateElseBlock">
<h3>templateElseBlock template</h3>
{{#isFemale gender}} Mrs. {{else}} Mr. {{/isFemale}}
</template>
<template name="isFemale">
{{#if eq this 'w'}}
{{> Template.contentBlock}}
{{else}}
{{> Template.elseBlock}}
{{/if}}
</template>
I tried something like this and got only errors
While building the application:
client/main.jade: Jade syntax error: unexpected token "indent"
<runJavaScript-57>:73:14: Cannot read property 'head' of undefined
(compiling client/main.jade) (at fileModeHandler)
template(name='templateElseBlock')
isFemale gender
| Mrs.
else
| Mr.
template(name="isFemale")
if eq #{this} 'w'
+Template.contentBlock
else
+Template.elseBlock
Does anybody know what to do?
After several google pages, I got that code needs only one symbol +isFemale.
The answer:
template(name='elseBlock')
+isFemale gender
| Mrs.
else
| Mr.
template(name="isFemale")
if eq this 'w'
+Template.contentBlock
else
+Template.elseBlock
Related
"guests": [
{
"guestname": "john smith",
"is_active": false,
"guestheight": "175cm",
"guestprofile": "https://www.example.com"
},
{
"guestname": "david smart",
"is_active": false,
"guestheight": "175cm"
}
]
I would like to check if guestprofile exist. Given that I currently have a variable holding the index of the list we are trying to access here, namely itemIndex. So basically I'm trying to query if guests[itemIndex]["guestprofile"] in handlebars.js context.
If I make a direct reference like
{{#if guests.0.guestprofile}}
//do something
{{/if}}
its working fine. However, if I replace 0 with itemIndex like below, everything broke...
{{#if guests.itemIndex.guestprofile}}
//do something
{{/if}}
Currently I have also tried
{{#if (lookup guests itemIndex).guestprofile}}
//do something
{{/if}}
{{#if guests[itemIndex].guestprofile }}
//do something
{{/if}}
None of them actually worked. Please help, Thank you in advance!
You were so close with your lookup attempt.
The issue is that Handlebars does not allow you to chain a key onto a lookup subexpression as you are doing with (lookup guests itemIndex).guestprofile. It just doesn't resolve dynamic variables that way, which is the same reason why lookup has to be used instead of guests.itemIndex.guestprofile.
The part you missed is that you actually need two lookups - one to get the element of guests at itemIndex and the second to get the guestprofile of that element.
Your template needs to become:
{{#if (lookup (lookup guests itemIndex) 'guestprofile')}}
do something
{{/if}}
I have created a fiddle for your reference.
How can I write an if not x statement in an HBS template file?
At present, I use an if/else clause in order to achieve that:
{{#if x}}
{{else}}
Some Text
{{/if}}
Is there a way to simplify this and use a single if statement?
I've tried stuff like {{#if !x}} and {{#if ^x}}, but it didn't work of course.
Looking on the web for HBS logical operators, I couldn't quite find the syntax for a logical-not.
Update
I should emphasize that in my case x is undefined.
I've learned it "the hard way", while trying:
{{#if not x}}
Some Text
{{/if}}
Which threw TypeError: Cannot read property 'includeZero' of undefined.
Have you tried unless?
<div class="entry">
{{#unless license}}
<h3 class="warning">WARNING: This entry does not have a license!</h3>
{{/unless}}
</div>
You can use the unless helper as the inverse of the if helper. Its
block will be rendered if the expression returns a falsy value.
https://handlebarsjs.com/builtin_helpers.html
You can also considers custom helpers:
Handlebars.registerHelper("ifNot", function(a, options){
if (!a) {
return options.fn(this);
}else{
try{
return options.inverse(this);
}catch(e){
//no else statement
}
}
});
Looking at this Using Blaze guide, it seems Blaze supports {{#if}} and {{else}} statements, but I have't seen examples of an if-else statement. Is this supported in Blaze? Or do I have to do an additional if block inside the else block, which can get ugly.
I tried {{else if}}, but that gave an error.
{{#if en}}{{text.en}}{{else if tc}}{{text.tc}}{{/if}}
Spacebars uses the same control flow structure as handlebars so the answer is the same as this one. In your case:
{{#if en}}
{{text.en}}
{{else}}
{{#if tc}}
{{text.tc}}
{{/if}}
{{/if}}
Side note - one of the nice things about jade is that it supports else if.
Sometimes a better alternative is to move the logic into a helper like this:
Template.myTemplate.helpers({
textValue: function() {
if (this.en) {
return this.text.tc;
} else if (this.tc) {
return this.text.tc;
}
}
});
<template name="myTemplate">
<p>{{textValue}}</p>
</template>
The current version of Blaze supports else if - see below for a sample format and reference to the github issue resolution.
{{#if isUserProfile}}
<h3>User Profile</h3>
{{else if isLawyerProfile}}
<h3>Lawyer Profile</h3>
{{else}}
<h3>Test</h3>
{{/if}}
Reference Link: GitHub Else If Issue Resoltion
Following on from #David Wheldon's excellent answer, it's also worth noting that you can pass parameters to your JavaScript helper functions from your Blaze template.
So, for example the code below selectively renders the options for a select list by calling the helper method with the line isSelected region customerCompany:
{{#if isSelected region customerCompany}}
<option value={{region._id}} selected>{{region.name}}</option>
{{else}}
<option value={{region._id}}>{{region.name}}</option>
{{/if}}
and then in the js file:
isSelected: function (region, customer) {
return customer.salesRegionId === region._id;
},
This approach of passing in your variables to your helpers is generally recommended to avoid the confusion that can the arise with the changing meaning of the this keyword when using templates.
I'm currently making a simple web app with meteor.js . I'm trying to implement a simple feature for my fantasy football league's custom site that I'm building.
Here's my code that's not working.
{{#each users}}
{{#if Meteor.userId() {{_id}} }}
{{> ownTradingBlock}}
{{else}}
{{> userTradingBlock}}
{{/if}}
{{/each}}
So basically I want to render a different template if the user in the list of league members is the current user that is logged in. Does anybody have any thoughts on how this is creating an error, and/or if there's a better way to do it?
Here's the error code I'm getting.
.html:67 : expected space
You cannot use a Meteor method within Spacebars. For this you will need to create a helper:
Template.yourTemplate.helpers({
isEq: function (id) {
if (Meteor.userId() === id)
return true;
return false;
}
});
Then in your template:
{{#each users}}
{{#if isEq _id}} }}
{{> ownTradingBlock}}
{{else}}
{{> userTradingBlock}}
{{/if}}
{{/each}}
I have started using Handlebars.js. It seems that there is no built in conditionals like else if.
I want to have something like this
{{#if type.one }}
do something ... IF
{{else if type.two}}
do something ... ELSE IF
{{else}}
do something ... ELSE
{{/if}}
But this doesn't work. How do I do ELSE IF with handlebars? Is writing a custom helper is the only option ? If yes then please provide some pointers to write this helper.
You can't do this with a custom helper as Handlebars if-ish helpers only understand two parts: the "if" part and the "else" part. You can nest things though:
{{#if type.one}}
do something ... IF
{{else}}
{{#if type.two}}
do something ... ELSE IF
{{else}}
{{#if type.three}}
...
{{else}}
...
{{/if}}
{{/if}}
{{/if}}
That sort of thing will get nasty fast so you probably don't want to do that. A better approach would (as usual with Handlebars) be to push the logic into your JavaScript so that at most one of type.one, type.two, type.three, ... would be true; then you could:
{{#if type.one}}
...
{{/if}}
{{#if type.two}}
...
{{/if}}
{{#if type.three}}
...
{{/if}}
If you have a lot of options for type or if the bodies in your {{#if}}s are complicated, you could switch to partials. You'd have to add a custom helper to build a partial name based on a template variable though; something like this:
Handlebars.registerHelper('show_type', function(type) {
var types = ['one', 'two', 'three'];
var partial;
for(var i = 0; i < types.length; ++i) {
if(!type[types[i]])
continue;
partial = '_partial_' + types[i];
break;
}
if(partial)
return Handlebars.partials[name](this);
else
return '';
});
and then, assuming your partials are all registered and consistently named, you could say:
{{show_type type}}
Since Handlebars 3.0 the syntax described by OP does work out of the box! See: https://github.com/wycats/handlebars.js/pull/892 for more information.
Note:
For Ember, since version 1.10 and up this does work too. See also:
http://emberjs.com/blog/2015/02/07/ember-1-10-0-released.html#toc_chained-else-blocks
if you are using ember like framework,
{{#if isAtWork}}
Ship that code!
{{else if isReading}}
You can finish War and Peace eventually...
{{/if}}
link : http://guides.emberjs.com/v1.12.0/templates/conditionals/
You can do this:
{{#if type.one}}
...
{{else}} {{#if type.two}}
...
{{else}} {{#if type.three}}
...
{{else}}
...
{{/if}}{{/if}}{{/if}}
If you want a switch behaviour, you might be interested in Dan Harper's helpers, you will be able to do something like :
{{#is type 1}}
<p>Do something when 1.</p>
{{else}}{{#is type 2}}
<p>Do something when 2.</p>
{{else}}{{#is type 3}}
<p>Do something when 3.</p>
{{/is}}{{/is}}{{/is}}
Here is the jsfiddle.
The exact syntax that the OP has written will work in Ember Canary today with the
ember-htmlbars-inline-if-helper feature flag enabled.