Handlebars Array Cycle - handlebars.js

I have this array:
{{#each weather.today }}
<p class="VNAelement timeStamp">BlaBla</p>
<p class="VNAelement">{{ rr }}mm</p>
{{/each}}
Now there will be three loops and on each loop the text BlaBla should be replaced. What is the best way to do this? The data comes from a json API but that string is set manuall.

The best solution is to write a custom helper to check the array index during traversal.
But here, as you are sure of the number of loops (which is 3 array items), you can rely on the #first and #last data-variables.
{{#each weather.today}}
<p class="VNAelement timeStamp">
{{#if #first}}
BlaBla-1 <!-- First item -->
{{else}}
{{#if #last}}
BlaBla-3 <!-- Third item -->
{{else}}
BlaBla-2 <!-- Second item -->
{{/if}}
{{/if}}
</p>
<p class="VNAelement">{{ rr }}mm</p>
{{/each}}

Related

Adding a css class in a dynamically created handlebars template

I have a JSON object that I am looping through to dynamically create x amount of ULs then LIs. I need to create two {{#each}} to create the content. However when I add a CSS class to my handlebars template it does not come through onto the UL as it does in the second {{#each}} - how do I stop this? Here is the template:
<div class="{{panel-container__Css-class}} {{panel-menu__Css-class}}" data-component="panel">
{{#each sections}}
<ul id="{{id}}" class="{{panel-menu__Css-class}}">
{{#each list}}
<li>{{title}}</li>
{{/each}}
</ul>
{{/each}}
</div>
Here is what i am passing in:
<nav data-component="navigation">
{{> nav-dropdown menu-button__Css-class="menu-button" menu-button__Css-class-nav="panel" target-id="panel-nav" }}
{{> nav-dropdown menu-button__Css-class="region-button" menu-button__Css-class-nav="region" target-id="panel-region" menu-button__copy=panel.copy}}
{{!--var links = [{"title": "Test","url": "/"}];--}}
{{> panel panel-menu__Css-class="navigation__menu-styles" panel-container__Css-class="navigation__menu-container" sections=navigation.sections links=navigation.sections.list }}
</nav>
I think what you are looking for is the Handlebars path that will allow you to obtain the value of panel-menu__Css-class from within {{#each sections}}. You need to understand that when you are within {{#each sections}}, your this context is the currently iterated element of the sections array. You must step up a level to the parent context which has the panel-menu__Css-class property you are trying to access:
<ul id="{{id}}" class="{{../panel-menu__Css-class}}">

get the `top 4 products from each toptier category sorted by date-added (to bigcommerce)`

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}}

How can I avoid duplicate templates in Meteor?

So I'm building my first app with meteor, and I feel like I'm repeating myself with my templates more than I should be.
I have multiple parent views, an example of which is the user contacts view, and the add group members view. (simplified examples below.)
<template name="GroupMembers">
{{#each contacts}}
{{> contact }}
{{/each}}
</template>
<template name="contacts">
{{#each contacts}}
{{> contact }}
{{/each}}
</template>
<template name="contact">
//... single contact template stuff
</template>
When the contact is displayed in the contacts list, I want to display a remove from contacts link in the single contact template, but in the group members list I'd like an 'add to group' link in its place. I know I could probably achieve this with either session variables or by invoking the iron-router controller obj, but I'd like to know if there is a simple way to do this in the template helper(s). Or put another way can these template partials become context aware?
Any help would be great.
Thanks.
I would solve it this way:
<template name="GroupMembers">
{{#each contacts}}
{{> contact groupMembers=true}}
{{/each}}
</template>
<template name="contacts">
{{#each contacts}}
{{> contact }}
{{/each}}
</template>
<template name="contact">
<p>
{{#if groupMembers}}
{{../name}}
<button>add to group</button>
{{else}}
{{name}}
<button>delete</button>
{{/if}}
</p>
</template>
Live demo: http://meteorpad.com/pad/LDTvHC787kJ6e9JQA/Leaderboard

How to do recursive templates in Meteor?

rather a theoretical question - how can I render recursive templates in Meteor? For example, displaying a comment on comment with unlimited number of comment sub-levels so that HTML would be diplayed as the following?
<section>
some text
<section>
nested text
<section>
further nested text and sections
.....
</section>
</section>
</section>
In my case I pass to the "tree" template a mongoDB document and this document can have unlimited number of sub-content levels. My example below doesn't work the way I want.
<template name="tree">
<div class="wrapper" style="border:1px solid red">
<ul>
{{#each getStructure}}
<li>
{{#each content}}
<ul>
<li>
<a class="item">{{text}}</a>
<!-- TODO: this stuff needs to be recursive.
{{#if sub_content}}
<ul>
{{#each sub_content}}
<li>
<a class="item">{{text}}</a>
{{#if sub_content}}
....
{{/if}}
</li>
{{/each}}
</ul>
{{/if}}
</li>
</ul>
{{/each}}
</li>
{{/each}}
</ul>
</div>
</template>
A simplified example of recirsuve, say you had a post sample template of:
<template name="post">
{{post_text}}
{{#each comments}}
{{>comment}}
{{/each}}
</template>
and a post helper of:
Template.post.helpers({
comments: function() {
return CommentCollection.find({post_id: this._id, parent_id: {$exists: 0}});
}
});
I would create a template for the comment layout and provide a helper in that for sub-comments, depending on your data structure something like the following:
<template name="comment">
{{comment_text}}
{{#each sub_comment}}
{{> comment}}
{{/each}}
</template>
and then the helper along the lines of:
Template.comment.helpers({
sub_comments: function() {
return CommentCollection.find({parent_id: this._id});
}
});
This would recursively produce the comments template for each sub-comment then roll back up the tree to the next #each and then print that comment and all of its sub-comments etc.

How to filter the data from a collection loop?

Im trying to build a related info widget, based on the data from the YAML front-matter.
Each page on my collection has some tags associated, and the idea would be to only show those pages who have tags in common with the currently viewed page.
I've managed to get the complete tags outputting the existent pages with the following code:
<section class="see-also">
{{#each tags}}
<p>In <span class="tag">{{tag}}</span>:</p>
{{#each pages}}
<li>{{data.title}}</li>
{{/each}}
{{/each}}
</section>
Can I apply some sort of filter on {{#each tags}} ?
Thanks.
There's an inArray helper that you can use to test if the current tag is in the tags collection on the page being currently rendered:
<section class="see-also">
{{#each tags}}
{{#inArray ../page.tags tag }}
<p>In <span class="tag">{{tag}}</span>:</p>
{{#each pages}}
<li>{{data.title}}</li>
{{/each}}
{{/inArray}}
{{/each}}
</section>
You might have to modify the parent path syntax to account for the additional block helper:
<section class="see-also">
{{#each tags}}
{{#inArray ../page.tags tag }}
<p>In <span class="tag">{{tag}}</span>:</p>
{{#each ../pages}}
<li>{{../data.title}}</li>
{{/each}}
{{/inArray}}
{{/each}}
</section>

Resources