How can I take data from certain posts when running a Jekyll cycle?
For example, I need post number 3.
Here's my loop:
{% for post in paginator.posts %}
<h2>{{ post.title }}</h2>
{% endfor %}
Related
1. The problem.
I want to sort sold out products at the bottom of a Shopify collection using liquid, in a customized version of the Dawn theme.
I tried filtering the product loop twice using opposing criteria, and it works to some extent. The main issue is that the pagination renders both loops per page, rather than rendering the whole collection and then paginating it.
So in a collection with 100 products, 30 sold out, and 5 pages with 24 products per page, the goal is for the 30 sold out products to take up pages 4 and 5. With my current code, it only pushes the sold out products in the first 24 spots to the bottom of that page, making the rest of the collection appear sold out when the user scrolls to the bottom.
This is what I have tried so far:
<div id="CollectionProductGrid">
{%- paginate collection.products by section.settings.products_per_page -%}
{%- if collection.products.size == 0 -%}
<div class="collection collection--empty page-width" id="main-collection-product-grid" data-id="{{ section.id }}">
<div class="loading-overlay gradient"></div>
<p class="collection-product-count light" role="status">
{%- if collection.products_count == collection.all_products_count -%}
{{ 'sections.collection_template.product_count_simple' | t: count: collection.products_count }}
{%- else -%}
{{ 'sections.collection_template.product_count' | t: product_count: collection.products_count, count: collection.all_products_count }}
{%- endif -%}
</p>
<div class="title-wrapper center">
<h2 class="title title--primary">
{{ 'sections.collection_template.empty' | t }}<br>
{{ 'sections.collection_template.use_fewer_filters_html' | t: link: collection.url, class: "underlined-link link" }}
</h2>
</div>
</div>
{%- else -%}
<div class="collection page-width">
<div class="loading-overlay gradient"></div>
<ul id="main-collection-product-grid" data-id="{{ section.id }}" class="
grid grid--1-col negative-margin product-grid
{% if collection.products_count < 4 %} grid--{{ collection.products_count }}-col-tablet{% else %}
{% if collection.products_count == 4 %} grid--4-col-desktop{% else %} grid--3-col-tablet grid--one-third-max grid--4-col-desktop grid--quarter-max{% endif %}
{% endif %}">
{% comment %}--Loops through available products first--{% endcomment %}
{%- for product in collection.products -%}
{%- if product.available -%}
<li class="grid__item">
{% render 'product-card',
product_card_product: product,
media_size: section.settings.image_ratio,
show_secondary_image: section.settings.show_secondary_image,
add_image_padding: section.settings.add_image_padding,
show_vendor: section.settings.show_vendor,
show_image_outline: section.settings.show_image_outline,
show_rating: section.settings.show_rating,
show_atc: section.settings.show_atc
%}
</li>
{%- endif -%}{%- endfor -%}
{%- for product in collection.products -%}
{%- unless product.available -%}
<li class="grid__item">
{% render 'product-card',
product_card_product: product,
media_size: section.settings.image_ratio,
show_secondary_image: section.settings.show_secondary_image,
add_image_padding: section.settings.add_image_padding,
show_vendor: section.settings.show_vendor,
show_image_outline: section.settings.show_image_outline,
show_rating: section.settings.show_rating,
show_atc: section.settings.show_atc
%}
</li>
{%- endunless -%}{%- endfor -%}
</ul>
{%- if paginate.pages > 1 -%}
{% render 'pagination', paginate: paginate, anchor: '' %}
{%- endif -%}
</div>
{%- endif -%}
{%- endpaginate -%}
</div>
The issue is the pagination, and it seems to be a difficult one to manipulate for an inexperienced coder like myself, so there are still other options I believe might work.
Either 1: Sorting
Creating a custom sorting order, if that is even possible. Since the sorting works with the pagination, this might be one of the easier ways to achieve this I believe, but I don't know how.
2: Using the filters and re-rendering the collection with javascript
This is far from ideal in terms of performance and UX, but might work as a hack since the filters seem to render the collection very quickly in real-time after filtering.
3: Filtering the loop before rendering it, and before pagination.
This is what I believe will be the best solution.
I have looked into capturing the loop in an array, but I am struggling to putting it all together correctly. This post explains how you can do this: http://www.codeshopify.com/blog_posts/building-arrays-with-liquid-in-shopify
And here is some example code I believe might be helpful:
{% capture products_list %}
{% for product in collection.products%}
{{product.title}}|{{product.url}}|{{product.description}}|{{product.featured_image.src | product_img_url: 'medium' }}
{% if forloop.last == false %}::{% endif%}
{% endfor %}
{% endcapture %}
{% assign products_array = products_list | split: '::'%}
What I need help with for the last option, is to figure out what to capture, how to concatinate it properly, and then how to loop through the new and filtered array. Or, a better solution if there is one.
I want to make a custom collection in collection.liquid based on some conditional scenario and for this I applied concat, append and join but the problem is that it returns ProductDropProductDropProductDropProductDrop... or LazyProductDropCollectionLazyProductDropCollection instead of products. Following is the code snippet
{% assign custom_products = '' %}
{% for product in collections["paneer-easy-indie-bowls"].products %}
{% assign custom_products = custom_products | append: product %}
{% endfor %}
instead of append I tried both join and concat but returns ProductDropProductDropProductDropProductDrop...
{% assign custom_products = custom_products | concat: product %}
then I tried the following:
{% capture custom_products %}
{% for product in collections["paneer-easy-indie-bowls"].products %}
{{ custom_products }},{{ product.handle }}
{% endfor %}
{% endcapture %}
{% assign custom_products = custom_products | split: ',' %}
{% for product in custom_products %}
{{ product}}
{% endfor %}
but this code not appending the products in right way. I want products like same as{{collection.products}}. Any suggestion ?
If I read your pseudo-code correctly, you are trying to build a collection of products from a collection of products. Which leads to the question, why? Since you already have a perfect collection, use it as is!
I am creating a blog page, the post list page is in the form of different sized images. I need to be able to style each post list item individually so need to be able to access the post list array with twig and get posts.
So for example, when accessing a featured image from a post you can use:
post.featured_images[0].path
I would like to do this but to select the first post in list of posts.
Whatever you want to do with the first post you can access the first post using the iteration variable in the loop.
There are few iteration variables in Twig, I usually use loop.index variable.
For example:
{% for post in posts %}
{% if loop.index == 1 %}
{{ post.title }}
{# this is the first post title #}
{% else %}
{{ post.title }}
{# this is others posts title #}
{% endif %}
{% endfor %}
And as you go if loop.index == 2 so you can access the second post. If it equals 3 you can access the third post etc.
Another alternative would be loop.first.
{% if loop.first %}
{# It goes here if it's the first record of the loop #}
{% endif %}
{% if loop.last %}
{# It goes here if it's the last record of the loop #}
{% endif %}
To learn more about Twig's loop variables: http://twig.sensiolabs.org/doc/2.x/tags/for.html#the-loop-variable
Hello and thanks for reading my post!
I have a collection with multiple products. On a custom collection template, I want to show the tags only for those that contain multiple products (or when more than 1 product in that collection have the same tag)
I assume it would go something like:
{% for tag in collection.all_tags %}
{% if tag.product.size >= 1 %}
has more than 1 product.
{% endif %}
{% endfor %}
I've answered similar questions here and here.
You want something like this:
{% for tag in collection.all_tags %}
{% assign products_count = 0 %}
{% for product in collection.products %}
{% if product.tags contains tag %}
{% assign products_count = products_count | plus: 1 %}
{% endif %}
{% endfor %}
{% if products_count > 1 %}
{{ tag }}
{% endif %}
{% endfor %}
What is the correct way to comment out in the Liquid templating language?
In Liquid you comment out using the {% comment %} and {% endcomment %} tags:
{% comment %} This is a comment in Liquid {% endcomment %}
It doesn't matter if the comment is inline or a block comment.
{% comment %}
This is a block comment in Liquid
{% endcomment %}
If, like me, you are looking for a solution that actually comments out "anything"/everything between the comment tags (as described in the documentation), you can use the {% raw %} tag (in conjuction with the {% comment %} tag if you don't want anything rendered in the browser).
Example:
{% comment %}
{% raw %}
Here is some text that I don't want displayed and
{% some_liquid_stuff_that_I_don't_want_parsed %}
{% endraw %}
{% endcomment %}
will render nothing at all.
In contrast,
{% raw %}
Here is some text that I want displayed but
{% some_liquid_stuff_that_I_don't_want_parsed %}
{% endraw %}
will render
Here is some text that I want displayed but
{% some_liquid_stuff_that_I_don't_want_parsed %}
while
{% comment %}
Here is some text that I don't want displayed but
{% some_liquid_stuff_that_will_be_parsed %}
{% endcomment %}
may result in a syntax error or Liquid exception, depending on the validity of the Liquid inside the comment tags.
An example of where this becomes an issue is where some work-in-progress code has been commented out:
{% comment %}
{% if some test %}
some stuff to render
{% elsif... %}
unfinished code...
{% endcomment %}
Additional information on this GitHub thread.
Liquid allows you to leave un-rendered code inside a Liquid template by using the {% comment %} and {% endcomment %} tags.
Input:
Anything you put between {% comment %} and {% endcomment %} tags
is turned into a comment.
Output:
Anything you put between tags
is turned into a comment.
Reference documentation: Comment tag in Liquid
Starting with Liquid 5.4.0 you will be able to use a short inline comment that does not require a closing tag! The syntax is:
{% # This is a new inline comment! %}
As with other tags you can add hyphens to remove whitespace around it:
{%- # This is a new inline comment without whitespace! -%}
And even use multiple lines:
{%-
################################
# This is a really big block #
################################
-%}
More info is available in the merged PR.
In the liquid, using comment tag enclose the text to be commented inside the comment tag
{%comment%}
Text to be commented
{%endcomment%}
In liquid, you use {% comment %} and {% endcomment %} tags:
{% comment %} This would be commented out {% endcomment %}
You can also use it in block:
{% comment %}
This would also be commented out
{% endcomment %}
If the {% comment %} and {% endcomment %} tags would comment anything, including HTML elements and such:
{% comment %}
<div class="commented_out">
<p>This whole div would be commented out</p>
</div>
{% endcomment %}