I'm trying to implement my own tabs, each tab has his own content. The default selected tab is the tab 1. It loads the html content and the template just fine. When I try to switch to the other two tabs I get the following error message:
Error: Expected template or null, found: false
In this case the template rendered in the tab 1 is the same rendered in the tab 3. In the tab 1 works fine, in the tab 3 i get the error message.
{{#if isSeletedTab 1}}
<div class="col-sm-12 horizontal-list">
<div class="new-store-card">
<img src='./img/add.png' />
<br/>
<span class="new-store-text">Add a new</span>
<br/>
<span class="new-store-text">store</span>
</div>
{{#each store in stores}}
<div class="store-card-container">
{{#if isSelectedStore store.name}}
<div class="edit-store-button">
<img src="./img/edit.png" class="edit-store-button-icon"/>
</div>
{{/if}}
<div class="store-card" id={{store.name}} style="{{#unless isSelectedStore store.name}}opacity: 0.3;{{/unless}}">
<h5 class="store-card-name" id={{store.name}}>{{store.name}}</h5>
<span class="store-card-id" id={{store.name}}>{{store.externalId}}</span>
</div>
</div>
{{/each}}
</div>
{{> users}}
{{else isSeletedTab 2}}
{{> roles}}
{{else isSeletedTab 3}}
{{> users}}
{{/if}}
You are using the {{if}} and {{else}} the wrong way. You can't use condition inside the else and there is no else if in Blaze.
Your code should be like this :
{{#if isSeletedTab 1}}
{{> users}}
{{else}}
{{#if isSeletedTab 2}}
{{> roles}}
{{else}}
{{#if isSeletedTab 3}}
{{> users}}
{{/if}}
{{/if}}
{{/if}}
Related
BigCommerce Stencil
I totally winged the below snippet. But i need a hint on doing that the correct way. I basically need to get the top 4 products from each toptier category sorted by date-added (to bigcommerce)
{{#each categories}}
{{#each products sort:date-added limit:4}}
{{name}}
{{/each}}
{{/each}}
To add, the syntax I would use is the following. However, I don't have any evidence that such a way exists yet.
home.html
{{> components/product/all-products grid=products.all default_image=theme_settings.default_image}}'
all-products.html being a custom file.
all-products.html
{{#if grid}}
<section class="products-new {{theme_settings.background-for-new-products}}">
<div class="layout-container">
<h1 class="section-title">{{lang 'product.product_blocks.new_products.heading'}}</h1>
<div class="product-grid">
{{#each grid}}
{{> components/product/product-item this show_quickshop=true show_rating=true default_image=../default_image}}
{{/each}}
</div>
</div>
</section>
{{/if}}
I'm trying to create a comments component with Blaze but i don't know how to handle the replies.
This is the schema for the 'comment' element:
_id, authorId, message, replies (those are comment ids), isReply (boolean).
Then I created a template with html
{{#each message}}
<div class="message">
<h2>{{author}}</h2>
<p>{{message</p>
<a class="button">Reply</a>
</div>
{{#each replies}}
<div class="message">
<h2>{{author}}</h2>
<p>{{message</p>
<a class="button">Reply</a>
</div>
{{/each}}
{{/each}}
Well, how do I handle the replies of the replies? Any Idea?
You need to use the templates recursively! An example
In your case, something like the following:
{{#each message}}
<div class="message">
<h2>{{author}}</h2>
<p>{{message</p>
<a class="button">Reply</a>
</div>
{{#each replies}}
{{> reply}}
{{/each}}
{{/each}}
<template name="reply">
<div class="message">
<h2>{{author}}</h2>
<p>{{message</p>
<a class="button">Reply</a>
{{#each replies}}
{{> reply}}
{{/each}}
</div>
</template>
You'll need a replies helper for the reply template that gets the replies to that reply.
when I generate subtemplate in #each helper and i add parameter, then i lose data context, what is normally visible.
I found workaround by passing data fields to template by
{{> productItem parameter="test" name=name details=details}}
, but for more complicated collections that would be very tiresome... isn't there better option to solve that problem ?
<template name="main">
{{#each products}}
{{> productItem parameter="test"}}
{{/each}}
</template>
<template name="productItem">
<div class="product">
<p>{{name}}</p>
<p>{{details}}</p>
<p>{{parameter}}</p>
</div>
</template>
And javascript :
Template.main.helpers({
products: function(){
return Products.find({});
}
});
you are creating a new context ( it doesn't magically merge everything ), but its easy enough to include the original context.
you go :-
{{> productItem product=this parameter="test"}}
then
<template name="productItem">
<div class="product">
<p>{{product.name}}</p>
<p>{{product.details}}</p>
<p>{{parameter}}</p>
</div>
</template>
or
<template name="productItem">
<div class="product">
{{#with product}}
<p>{{name}}</p>
<p>{{details}}</p>
{{/with}}
<p>{{parameter}}</p>
</div>
</template>
I have 2 templates:
1) mainLayout.html -> general layout which must be used by all pages. (e.g. page title, navbar, footer)
Router.configure({
layoutTemplate: 'mainLayout'
})
<template name="mainLayout">
{{> header}}
<div class="container-fluid">
{{> yield}}
</div>
</template>
2) specialLayout.html -> custom layout which is inheriting main-layout.html but with additional template (e.g. side/tab menu)
How should I define specialLayout? Note that specialLayout should have the title, navbar, and footer defined in mainLayout.
If I have route X which want to use specialLayout, how should I write it?
I don't know any simple method at this moment, but most things can be achieved by several less elegant ways:
Copy your common parts into separate templates and use them in both layouts, i.e.:
<template name="mainLayout">
{{> navbar}}
<div>
{{> content}}
</div>
{{> footer}}
</template>
<template name="specialLayout">
{{> navbar}}
<div>
{{> content}}
{{> sidebar}}
</div>
{{> footer}}
</template>
Make your special part an option in the main layout instead of a separate one:
<template name="mainLayout">
...
<div>
{{#if layout.renderSidebar}}
<div class="col-2">>
{{> yield 'sidebar'}}
</div>
{{/if}}
<div class="{{#if layout.renderSidebar}} col-10 {{else}} col-12 {{/if}}">
{{> yield}}
</div>
</div>
...
</template>
Then in the appropriate routes enable sidebar in the data:
this.map('pathName', {
...
data: function() {
return {
layout: {renderSidebar: true},
...
};
},
});
I am getting a frustrating error because of my Handlebars JS templates.
Error: Parse error on line 9:
... {{/each}} {{/if}}
----------------------^
Expecting 'EOF'
Handlebars in question:
{{if showSingle}}
{{#with single}}
{{> postSingle}}
{{/with}}
{{else}}
{{#each posts}}
{{> postItem}}
{{/each}}
{{/if}}
Is nesting like this not possible?
Just to put things in context, this was working fine:
{{#each posts}}
{{> postItem}}
{{/each}}
Missing the # from the first if:
{{#if showSingle}}
{{#with single}}
{{> postSingle}}
{{/with}}
{{else}}
{{#each posts}}
{{> postItem}}
{{/each}}
{{/if}}