Shopify - Insert image between list of items - php

I am trying to list a load of products, and insert an image between the second last and the last item. At the moment I have this code on my index:
<ul class="clearfix">
{% for product in collections.drinks.products %}
{% include 'snippet-product-item' with 'four' %}
{% endfor %}
</ul>
This in my product-item:
{% if snippet-product-item == '' %}{% assign snippet-product-item = 'four' %}{% endif %}
<li class="{{ snippet-product-item }}-per-row clearfix">
<div class="coll-image-wrap{% unless product.available %} sold-out{% endunless %}">
{% if product.available == false %}
{% assign ratio = settings.product_img_w_to_h_ratio | times: 1.0 %}
<a href="{{ product.url | within: collection }}">
<img src="{{ product.featured_image.src | product_img_url: 'large' }}" alt="{{ product.featured_image.alt | escape }}" />
</a>
</div><!-- .coll-image-wrap -->
</li>
So I'm guessing I need to put some code in my index block to work out how many items there are in the collection, and then for the last one add an extra image in before it. Can anyone help me figure out how that might be done please?
This is my useless attempt:
{% assign num = 0 %}
{% for product in collections.drinks.products %}
//Do something like this to work out number of items in collection
{% assign num = temp %}
// Then minus one and insert the image so it appears between second to last and last items
{% endfor %}

I would try something like this:
{% for product in collections.drinks.products %}
{% if forloop.last %}
// Insert image...
{% endif %}
{% include 'snippet-product-item' with 'four' %}
{% endfor %}

Related

get first item in loop

I am looping through an array and would like to add a class if it is the first item.
I have tried
{% if field|first %}
{% if field.first %}
{% if field.first() %}
{% if loop|first %}
{% if loop.first %}
{% if loop.first() %}
none work, please help. (the reason I don't use css pseudo first is that this is a grid layout and I have am doing responsive layout things with it)
{% for field in row.fields %}
<div class="c-product-table__item {% if field|first %}{{ first_item }}{% endif %} ">
<span class="c-product-table__text">{{ field.text }}</span>
</div>
{% endfor %}
I don't know why twig filters are not working, I solved it another way. I set a var and made it blank after first loop
{% set thiscount = 'first_item' %}
{% for field in row.fields %}
<div class="c-product-table__item {{ thiscount }}">
<span class="c-product-table__text">{{ field.text }}</span>
</div>
{% set thiscount = '' %}
{% endfor %}

Render a form ONLY ONCE inside a for loop in a twig template

I have a twig template to display audio options (Auto play and Continuos play) as shown in the screen shot:
Click to see the screen shot of the page
The following is the code in my twig file. {{ audio_options_form}} renders the form with the checkboxes.I want to display the check boxes only once if {{ item.audio }} is true. Please let me know what changes should I make:
<div id="textcontent">
{% set field = data|slice(2) %}
{% set field = field|slice(0, -1) %}
<div class="col-md-12">
<div class = "source-box audio">
{% for item in field %}
{% if item.audio %}
{{ audio_options_form }}
{% if data.play.autoplay == 1 %}
<audio autoplay controls src= "{{item.audio}}" id = "audio-play">
Your browser does not support the
<code>audio</code> element.
</audio>
{% elseif data.play.continuousplay == 1 %}
<audio autoplay controls src= "{{item.audio}}" id = "audio-play" onended="continousPlay('{{data.lastlevel}}')">
Your browser does not support the
<code>audio</code> element.
</audio>
{% else %}
<audio controls src= "{{item.audio}}" id = "audio-play">
Your browser does not support the
<code>audio</code> element.
</audio>
{% endif %}
<div id="source-controls">
{# {% if allow_edit == 1 %}
<a class="edit-text" href="{{ path('heritage_text_manager.editsource', {'sourceid': item.uniqueid}, {'query': {'destination': path('heritage_ui.contentpage', {'textid': textid})}}) }}">{{ 'Edit'|t }}</a>
{% endif %} #}
<a class="more use-ajax" data-toggle="modal" data-dialog-type="modal" href="{{ path('heritage_ui.metadata', {'sourceid': item.uniqueid}) }}">{{ 'More'|t }}</a>
</div>
{% endif %}
{% endfor %}
</div>
Either create a 2nd loop with a flag or use the filter filter.
{% set show_audio_form = false %}
{% for item in field %}
{% if item.audio %}
{% set show_audio_form = true %}
{% endif %}
{% endfor %}
{% if show_audio_form %}{{ audio_options_form }}{% endif %}
{% for item in field %}
... display audio ...
{% endfor %}
{% if items|filter(v => v.audio|default)| length %}
{{ audio_options_form }}
{% endif %}
{% for item in items %}
... display audio ...
{% endfor %}
demo

Twig show n keys of array or all

I have an editor with a set of buttons, and I want to display only a set of buttons based on twig::render variables.
If I include all I want it to display are buttons available, if I include individual button keys I want to display only that ones.
echo TwigLoader::render('#ui/editor.html.twig'['toolbar'=>['all']]);
echo TwigLoader::render('#ui/editor.html.twig'['toolbar'=>['font','size']]);
For the template I'm using the following code:
{% set toolbar_tools = [
{'font':'<select class="ql-font"></select>'},
{'size':'<select class="ql-size"></select>'}]
%}
<div id="button-container">
<span class="ql-formats">
{% for tool, key in toolbar_tools %}
{{ tool.key|raw}}
{% endfor %}
</span>
</div>
I'm getting an empty container.
Is this a good strategy or there are better ways?
Seems you`re looking for something like this:
{% set toolbar_tools = {
'font':'<select class="ql-font"></select>',
'size':'<select class="ql-size"></select>'
}
%}
<div id="button-container">
<span class="ql-formats">
{% if toolbar|length > 0 %}
{% for t in toolbar %}
{% if t == 'all' %}
{# show all options #}
{% for tool in toolbar_tools %}
{{ tool|raw }}
{% endfor %}
{% else %}
{# show defined options #}
{{ attribute(toolbar_tools, t)|raw }}
{% endif %}
<br />
{% endfor %}
{% endif %}
</span>
</div>
Hope you will be fine with that.

How to do a for loop in liquid with range

I am attempting to have a for loop in my template to loop through each letter of the alphabet, and if the first letter of the alphabet is found, print out that data.
I cannot find a way to do this, i know how to do this in PHP, but cannot get it to work in liquid.
{% for range('a','z') as $i %}
{% if first_letter == $i %}
{% unless first_letter == current %}
<li class="test"><h2 id='{{ first_letter }}'>{{ first_letter }}</h2> </li>
{% endunless %}
<ul><li class="test"> {{ product_vendor | link_to_vendor }} </li> </ul>
{% assign current = first_letter %}
{% endif %}
{% endfor %}
The top two lines is what is not working here, i know the syntax is incorrect, but i cannot figure out how to get this to work.
The syntax for ranges in liquid for loops is here in the Shopify docs:
{% assign num = 4 %}
{% for i in (1..num) %}
{{ i }}
{% endfor %}
{% for i in (3..5) %}
{{ i }}
{% endfor %}
However, you can only use numbers in the range, not strings.
Have you seen this article? Maybe that approach would work in your situation.
Edit: Updated link for above article.
We are talking about liquid here, so you don't have many options. This will work fine, but make sure you complete alphabet.
{% assign letters = "a b c d e f g h i j" | split: ' ' %}
{% for letter in letters %}
{% if letter == 'g' %}
<!-- Letter {{ letter }} match! -->
{% endif %}
{% endfor %}

Related products not showing up on shopify

I have this code on my related products:
<h3>HAVE YOU TRIED...</h3>
{% assign max = 10 %}
{% assign count = '' %}
{% assign list = '' %}
{% capture list %},{{ product.id }}{% endcapture %}
{% for collection in product.collections %}
{% if collection.handle contains 'related' %}
{% for product_related in collection.products %}
{% capture id %},{{ product_related.id }}{% endcapture %}
{% unless list contains id %}
{% if count.size < max and product_related.images.size > 0 %}
<div class="rel-product">
<div class="rel-img">
{% for image in product_related.images offset:1 limit:1 %}
<img src="{{ image.src | product_img_url: 'compact' }}}" alt="" />
{% endfor %}
</div>
<div class="rel-cnt">
<h6>{{ product_related.title }}</h6>
<p>{{ variant.option1 }}</p>
<span class="price">{{ product_related.price | money }}</span>
</div>
</div>
{% capture count %}{{ count }}.{% endcapture %}
{% capture list %}{{ list }}{{ id }}{% endcapture %}
{% endif %}
{% endunless %}
{% endfor %}
{% endif %}
{% endfor %}
It seems to work fine for products in one collection but not at all for products in another collection, the "have you tried" box is empty. Can anyone tell me what this code is doing in terms of picking related products in shopify and why it might not be showing any related products for items in that collection.
Firstly print your 'product' array and check what it will return to you while checking for other one.

Categories