I'm building a Jekyll site that has a page that displays product information from a JSON file. I was wondering if it would be possible to filter what products are displayed by the corresponding quantity listed in another CSV file with stock numbers. Both of these files use the same identifier for each product. E.G. something along the lines of:
{% for product in site.data.products %}
{% if product.identifier == stock.identifier and current-stock < X %}
Display the product
{% endif %}
{% endfor %}
You can use the where filter :
<ul>
{% for product in site.data.products %}
<li>
{% assign id = product.identifier %}
{% assign data = site.data.stock | where: "identifier", id | first %}
{% if data %}
{{ data | inspect }}
{% else %}
No data available
{% endif %}
</li>
{% endfor %}
</ul>
Related
I'm trying to loop through all the collections that a set of products is part of. This is my code:
<div class="container model-collection">
<h1>{{ collection.title }}</h1>
{% paginate collection.products by 12 %}
<div class="grid collection-products-container">
<ul>
{% for product in collection.products %}
{% for collection in product.collections %}
<li>{{ collection.title }}</li>
{% endfor %}
{% endfor %}
</ul>
</div>
{% if paginate.pages > 1 %}
{% include 'pagination' %}
{% endif %}
{% endpaginate %}
</div>
This works fine, however if two products are part of the same collection it lists that collection twice. So I need to limit the loop that it only shows each collection once.
I've tried to do it like this:
<div class="container model-collection">
<h1>{{ collection.title }}</h1>
{% assign model = collection.title %}
<div class="grid collection-products-container">
<ul>
{% for product in collection.products %}
{% assign seen_collections = "" %}
{% for collection in product.collections %}
{% unless seen_collections contains collection %}
{% assign seen_collections = seen_collections | append: "," | append: collection %}
<li>{{ collection.title }}</li>
{% endunless %}
{% endfor %}
{% endfor %}
</ul>
</div>
</div>
But this only returns one of the collections twice and none of the others. Any ideas how to do this?
You can get an aggregate list of nested properties by using the map filter in your Liquid code, and the map filter lets you drill into nested objects quite efficiently.
So to get an array of all the unique collection handles used by all the products in your collection, we can quickly get the info we want as:
{% assign collection_handles = collection.products | map: 'collections' | map: 'handle' | uniq %}
This creates an array of all the collection handles of all the products inside the collection, then reduces them to just the unique ones (using the uniq filter). Note: uniq needs to work with a number, string, or other simple field - which is why we needed an array of collection handles, not an array of collection objects.
So now you can do your loop as:
{% for handle in collection_handles %}
{% assign collection = collections[handle] %}
<!-- All your awesome stuff here -->
{% endfor %}
Hope this helps!
I'm creating some templates with Twig and have an issue.
I'm trying to load a piece of html that is used several times troughout a webshop. So my idea is to create a reusable piece of code that I can load everytime when needed.
The problem I'm facing is that when I do a for loop and then include that piece of code I get an empty return. With other words my code doesn't recognize the data that need to be loaded for each product in the for loop. It returns empty info boxes.
To clarify:
I have a main template index.html which calls a snippet to include some products (don't look at rain extension!!):
{% if featured %}
{% include 'snippets/products.rain' with {'products': featured, 'type': 'grid'} %}
{% endif %}
My products.rain snippet looks like this:
{% if type %}
{% if type == 'grid' %}
{% for product in products %} {# Products in this case = feautured products #}
<li class="item clearfix">.... etc etc .... </li>
{% endfor %}
{% elseif type == 'other-layout' %}
<div class="item">.... etc etc .... </div>
{% endif %}
{% endif %}
In the for loop there's html that's for 95% the same as in each for loop. I want to place that code inside a block that can be included in the for loops.
So what I did was:
{% set product_html %}
.... a lot of html ....
<a href="{{ product.url | url }}" title="{{ product.fulltitle }}">
<img src="{{ product.image }}" width="100" height="100" alt="{{ product.fulltitle }}"/>
</a>
{% endset %}
And then included in the for loop, like so:
{% if type %}
{% if type == 'grid' %}
{% for product in products %} {# Products in this case = feautured products #}
<li class="item clearfix">{{ product_html | raw }}</li>
{% endfor %}
{% elseif type == 'other-layout' %}
<div class="item">{{ product_html | raw }}</div>
{% endif %}
{% endif %}
However this returns the html that is set however with empty product.image and empty product.fulltitle.
I tried the same with set block, but that has the same result.
Is there anything I'm doing wrong....??
When you are using {% set %}, content inside your variable is not dynamic, it will only use data in your current context, see it live.
You can achieve your goal using 2 ways: using include or using macros.
As your piece of code for a product is small and not reused somewhere else, I suggest you to use macros:
{% macro product_html(product) %}
Current product is: {{ product }}
{% endmacro %}
{% import _self as macros %}
{% for product in products %}
{{ macros.product_html(product) }}
{% endfor %}
See it live
I want to loop through posts on a site except ones with the category unlisted. I'm able to do this by nesting an if statement inside the for loop, but this breaks down when I want to also specify a limit – the loop will run for 5 times only regardless of whether the post passes the check.
{% for post in site.posts limit: 5 %}
{% unless post.categories contains 'unlisted' %}
<!-- display post -->
{% endunless %}
{% endfor %}
I need to pass an already filtered list to the for loop, but I'm unable to do this mainly because I can't find a way to combine the where filter with contains and negation:
{% for post in site.posts | WHERE CATEGORIES NOT CONTAINS 'UNLISTED' | limit: 5 %}
<!-- display post -->
{% endfor %}
You can use a counter :
<ul>
{% assign postCounter = 0 %}
{% assign maxPost = 5 %}
{% for post in site.posts %}
{% unless post.categories contains 'unlisted' %}
<li>{{ post.title }}</li>
{% assign postCounter = postCounter | plus: 1 %}
{% if postCounter >= maxPost %}
{% break %}
{% endif %}
{% endunless %}
{% endfor %}
</ul>
I want to loop over all items in a collection that have a certain field set (not empty). I tried this:
{% assign papers_with_demos=site.data.papers | where:"demo", not blank %}
{% if papers_with_demos.size > 0 %}
<h2>demos</h2>
{% for paper in papers_with_demos %}]
...
{% endfor %}
{% endif %}
but it does not work; all papers are returned.
My goal is that the heading "demos" will be shown, only if there is one or more paper with a demo.
If papers are being returned, you must be using data files. If a value is empty for a particular key in a data file it will return false. So you could check the data key with a forloop like:
{% for paper in site.data.papers %}
{% if paper.demo %}
something
{% endif %}
{% endfor %}
You'll find more info in the Data Files section of the Jekyll documentation.
Updated in response to your reply:
{% for item in site.data.items %}
{% if item.random %}
{% assign random-val = item.random %}
{% if random-val %}
<p>true</p>
{% endif %}
{% endif %}
{% endfor %}
This will return true if inside items.yml, you have - random: true, nothing if empty.
I want to display keywords and description automatically according to the category of the current post. I've used the following code, but it doesn't worked.
{% if page.categories = "category" %}
{% else %}
{% endif %}
But while using {% page.categories %} it is echoing out the category name correctly. Here are my two doubts:
How can I compare the current post's category?
Are {{ }} and {% %} are same here?
It should look like the following:
{% if page.categories == 'some-name' %}
Hei I am in some-name category
{% else %}
No I am not in some-name category
{% endif %}
2.
No, {{ }} and {% %} are not the same. {{ }} is used for echoing stuff, while {% %} is used for logic expressions and arguments.