How to only display the available product variant prices in the products overview - shopify

I would like to display the lowest price of the available/instock product variants, instead of "From " + the lowest price of all product variants, even if they are not in stock. I am using the theme Prestige, any hints on how I could achieve this?
If I am right, I found the following code part in product-item.liquid which is displaying the price and also rendered in the flickity carousel and products overview pages:
<div class="ProductItem__PriceList {% if show_price_on_hover %}ProductItem__PriceList--showOnHover{% endif %} Heading">
{%- if product.compare_at_price > product.price -%}
<span class="ProductItem__Price Price Price--highlight Text--subdued">{{ product.price | money_without_trailing_zeros }}</span>
<span class="ProductItem__Price Price Price--compareAt Text--subdued">{{ product.compare_at_price | money_without_trailing_zeros }}</span>
{%- elsif product.price_varies -%}
{%- capture formatted_min_price -%}{{ product.price_min | money_without_trailing_zeros }}{%- endcapture -%}
{%- capture formatted_max_price -%}{{ product.price_max | money_without_trailing_zeros }}{%- endcapture -%}
<span class="ProductItem__Price Price Text--subdued">{{ 'collection.product.from_price_html' | t: min_price: formatted_min_price, max_price: formatted_max_price }}</span>
{%- else -%}
<span class="ProductItem__Price Price Text--subdued">{{ product.price | money_without_trailing_zeros }}</span>
{%- endif -%}
</div>
{%- if product.selected_or_first_available_variant.unit_price_measurement -%}
<div class="ProductItem__UnitPriceMeasurement">
<div class="UnitPriceMeasurement Heading Text--subdued">
<span class="UnitPriceMeasurement__Price">{{ product.selected_or_first_available_variant.unit_price | money_without_trailing_zeros }}</span>
<span class="UnitPriceMeasurement__Separator">/ </span>
{%- if product.selected_or_first_available_variant.unit_price_measurement.reference_value != 1 -%}
<span class="UnitPriceMeasurement__ReferenceValue">{{ product.selected_or_first_available_variant.unit_price_measurement.reference_value }}</span>
{%- endif -%}
<span class="UnitPriceMeasurement__ReferenceUnit">{{ product.selected_or_first_available_variant.unit_price_measurement.reference_unit }}</span>
</div>
</div>
{%- endif -%}
I tried to use the following code from the Shopify-Blog https://www.shopify.com/partners/blog/collection-page-price-range
{% if available %}
{% if product.price_varies and template == 'collection' %}
From {{ product.price_min | money }} to {{ product.price_max | money }}
{% else %}
{{ money_price }}
{% endif %}
{% else %}
{{ 'products.product.sold_out' | t }}
{% endif %}
This code however, displays the product as sold out.

It will be better if you set product_pricetocompare to the value of first variant.
This will check if there is a variant. If there is no variant, you will see 999999, which is not good.
example:
{% for variant in product.variants %}
{% if forloop.index == 1 %}
{% assign product_pricetocompare = variant.price %}
{% else %}
{% if variant.available %}
{% if variant.price < product_pricetocompare %}
{% assign product_pricetocompare = variant.price %}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}

Okay I found the answer, maybe it helps someone else as well. Loop through the variants and check if the variant is available and save the lowest price:
{% assign product_pricetocompare = 999999 %}
{% for variant in product.variants %}
{% if variant.available %}
{% if variant.price < product_pricetocompare %}
{% assign product_pricetocompare = variant.price %}
{% endif %}
{% endif %}
{% endfor %}

Related

Group Shopify products collections by Vendor in liquid template in Shopify v2

I am using Masonry theme , and I am trying to group the results for products in the collection by (vendor name and and link to the vendor collection).
I tried too many approaches and that the closest I could get due my limitation to using liquid , below is only showing the first set of products and only the vendor names for the rest
"**" that's my initial setup code and the rest is from the template.
<div class="cc-filters-results">
<div class="{% if settings.adv_ratio %}fixedlayout{% else %}blocklayout{% endif %} {% if section.settings.coll_infscr %}do-infinite{% endif %}">
{%- if collection.products != blank and settings.adv_ratio -%}
{%- capture calculated_aspect_ratio -%}{% render 'minmax-image-ratio', products: collection.products, type: settings.prod_thumb_img_ratio %}{%- endcapture -%}
{%- endif -%}
**{%- for vendor in collection.all_vendors -%}
<h2>{{ vendor }}</h2>
{%- assign products = collection.products | where: "vendor", vendor | limit: 1 -%}
{%- for product in products limit:3 -%}
{% render 'product-block', product: product, product_collection: collection, calculated_aspect_ratio: calculated_aspect_ratio %}
{% else %}
<div class="block text no-inf size-large"><div class="main">{{ 'collections.general.no_matches' | t }}</div></div>
{% endfor %}
{% endfor %}**
{% for i in (1..10) %}
<div class="block no-inf product block--flex-placeholder"></div>
{% endfor %}
</div>
{% if paginate.items > 0 %}
<div class="row pagination-row">
{% render 'pagination-control', paginate: paginate %}
</div>
{% endif %}
</div>

How can I exclude a vendor type using a ternary or unless?

In a page.[].liquid template there are numerous 'vendor' products to be listed. Some with and some without a collection association.
How can I exclude a specific vendor in a for loop using 'unless' or a ternary?
Neither of the following generate any output within the parent container.
<div style="height: 50px;" class="ptest">
{% assign collection = product.available %}
{% for product in collection.all_vendors %}
{% if product.collection != "acme" %}
<div>yes</div>
{{ product.name }}
{% else %}
<div>no</div>
{{ product.name }}
{% endif %}
{% endfor %}
{% for product in collection.all_vendors %}
{% unless product.vendor contains "acme" %}
<div>yes</div>
{{ product.name }}
{% else %}
<div>no</div>
{{ product.name }}
{% endunless %}
{% endfor %}
</div>
List all vendors except "acme":
{%- for vendor in collection.all_vendors -%}
{%- if vendor == "acme" -%}
{%- continue -%}
{%- endif -%}
{{ vendor }} is definitely not "acme"<br>
{%- endfor %}
List collection products except those with vendor "acme":
{%- for product in collection.products -%}
{%- if product.vendor == "acme" -%}
{%- continue -%}
{%- endif -%}
{{ product.name }} vendor is {{ product.vendor }}.<br>
{%- endfor -%}
Sorry, but your code is a mess:
{% assign collection = product.available %} - the collection is now boolean, either true or false
{% for product in collection.all_vendors %} - as of the above collection doesn't have all_vendors attribute.
{% if product.collection != "acme" %} - as of the above, this code will never be reached, but even if it will - the product object doesn't have collection attribute.
{{ product.name }} - where did you get this code? product doesn't have name attribute, you have to use title instead.
{% for product in collection.all_vendors %} - you go through vendors, why do you call them products?
{% unless product.vendor contains "acme" %} - as this is the next line after the above one, the product would be a vendor, not a product object, so you should use it as a string i.e. {% unless product contains "acme" %}
After a lot of searching, it looks like the only solution to displaying products that A. are 'all except' a single vendor and B. are not part of any collection, is to use a more simple if-math.
{% for product in collections.all.products %}
{% if product.collections.size < 1 && product.vendor != "acme" %}
<h3>
<a href="{{ product.url }}">
{{ product.title }}
</a>
</h3>
{% endif %}
{% endfor %}
Running through all products to loop those that are not part of a collection, generates the proper result.

Collection Filter Grouping - Customizing the User Experience

We would like to customize the collection group filtering. Currently, the group filtering is grouping and showing all product tags that have an underscore in the tag name.
ex: Brand_Premium
However, we would like to only show a filter group when there is more than one filter available within a group:
ex: All products on a given collection collection page are the same brand. In this case, we do not want to show a filter group for Brand, since there is only one option.
{%- capture tag_icon -%}
<span class="filter-icon--checkbox">
{%- include 'icon-checkbox' -%}
</span>
{%- endcapture -%}
{% for cat_item in cat_array %}
{% assign tag_count = 0 %}
<h3 class="productgrid--sidebar-title--small">
{{ cat_item }}
</h3>
<ul class="productgrid--sidebar-item filter-group">
{% for tag in collection.all_tags %}
{% assign cat = tag | split: '_' | first %}
{% if cat != tag and cat_item == cat %}
{% assign tag_count = tag_count | plus: 1 %}
{%- capture tag_text -%}
{{- tag_icon -}}
<span class="filter-text">
{{ tag | remove_first: cat | remove_first: '_' }}
</span>
{%- endcapture -%}
{% assign filter_class = 'filter-item' %}
{%- if current_tags contains tag -%}
{% assign filter_class = filter_class | append: ' filter-item--active' %}
{%- else -%}
{% assign filter_class = filter_class | append: ' filter-item--inactive' %}
{%- endif -%}
{%- if tag_count > tag_limit -%}
{% assign filter_class = filter_class | append: ' filter-item--hidden' %}
{%- endif -%}
<li
class="{{ filter_class }}"
data-tag-advanced
data-group="{{ cat_item }}"
data-handle="{{ tag | handle }}"
{% if tag_count > tag_limit %}data-hidden-default{% endif %}
{% if current_tags contains tag %}aria-current="true"{% endif %}
>
{% if current_tags contains tag %}
{{ tag_text | link_to_remove_tag: tag }}
{% else %}
{{ tag_text | link_to_add_tag: tag }}
{% endif %}
</li>
{% endif %}
{% endfor %}
{% if tag_count > tag_limit %}
<li class="filter-item">
<a class="filter-text--link" href="#" data-filter-toggle="false">
{{ 'general.general.see_more' | t }}
</a>
</li>
{% endif %}
</ul>
<hr />
{% endfor %}

Show variantimage as clickable thumnail on collectionpage/home page Shopify (brooklyn Theme)

i'm trying to show all variants (only color) of a product as a thumbnail on the collectionpage below each product. I want the customer to be able to preview all variants in on collectionpage before going to productpage. Can someone help me with pointing in the richt direction.
What i have is the following. This outputs the variantnames and names of the images but not the thumbnails. What i want is the variant image attached to that variant name. Preferable able to preview on collectionpage on hover.
Thanks!
<ul class="colorlist">
{% for option in product.options %}
{% if option == 'Color' %}
{% assign index = forloop.index0 %}
{% assign colorlist = '' %}
{% assign color = '' %}
{% for variant in product.variants %}
{% capture color %}
{{ variant.options[index] }}
{% endcapture %}
{% unless colorlist contains color %}
{% if variant.available %}
<li id="{{ variant.id }}" title="{{ variant.inventory_quantity }} In Stock" class="instock">{{ color | downcase }}</li>
{% else %}
<li id="{{ variant.id }}" title="Out of Stock" class="outstock" >{{ color | downcase }}</li>
{% endif %}
{% capture tempList %}
{{colorlist | append: color | append: " " }}
{% endcapture %}
{% assign colorlist = tempList %}
{{ product.selected_or_first_available_variant.featured_image }}
{% endunless %}
{% endfor %}
{% endif %}
{% endfor %}
</ul>

Only displaying available options on shopify

In Snippets/product-form.liquid there's a block of code:
<div class="swatch_options">
{% for option in product.options %}
{% include 'product-swatch' with option %}
{% endfor %}
</div>
This is displaying options for products with X's over the unavailable swatches:
<div data-value="option name" class="swatch-element color optionName-swatch available soldout">
<div class="tooltip">Option Name</div>
<label for="optionName">
<span class="crossed-out"></span>
</label>
</div>
When those non-compatible variants are clicked, a large "UNAVAILABLE" message is displayed:
<p class="modal_price" itemprop="offers" itemscope="" itemtype="http://schema.org/Offer">
<meta itemprop="priceCurrency" content="USD">
<meta itemprop="seller" content="site">
<link itemprop="availability" href="http://schema.org/InStock">
<meta itemprop="itemCondition" content="New">
<span class="sold_out">Unavailable</span>
<span itemprop="price" content="10.00" class="">
<span class="current_price "></span>
</span>
<span class="was_price"></span>
<span class="sale savings"></span>
</p>
I've tried checking for variant.available, product.variants.first.available, and variant.inventory_quantity > 0 before {% include 'product-swatch' with option %}, without success.
How do I hide the non-compatible variants?
Edit: Here's what's currently inside of product-swatch.liquid:
{% comment %}
Set the extension of your color files below. Use 'png', 'jpeg', 'jpg' or 'gif'.
{% endcomment %}
{% assign file_extension = 'png' %}
{% assign swatch = product-swatch %}
{% assign found_option = false %}
{% assign is_color = false %}
{% assign option_index = 0 %}
{% for option in product.options %}
{% if option == swatch %}
{% assign found_option = true %}
{% assign option_index = forloop.index0 %}
{% assign downcased_option = swatch | downcase %}
{% if downcased_option contains 'color' or downcased_option contains 'colour' %}
{% assign is_color = true %}
{% endif %}
{% endif %}
{% endfor %}
<div class="swatch clearfix" data-option-index="{{ option_index }}">
<div class="option_title">{{ swatch }}</div>
{% assign values = '' %}
{% for variant in product.variants %}
{% if variant.available %}
{% assign value = variant.options[option_index] %}
{% unless values contains value %}
{% assign values = values | join: ',' %}
{% assign values = values | append: ',' | append: value %}
{% assign values = values | split: ',' %}
<input id="swatch-{{ option_index }}-{{ value | handle }}-{{ product.id }}" type="radio" name="option-{{ option_index }}" value="{{ value | escape }}"{% if forloop.first %} checked{% endif %} />
<div data-value="{{ value | escape }}" class="swatch-element {% if is_color %}color {% endif %}{{ value | handle }}-swatch {% if variant.available %}available{% else %}soldout{% endif %}">
{% if is_color %}
<div class="tooltip">{{ value }}</div>
{% endif %}
{% if is_color %}
<label for="swatch-{{ option_index }}-{{ value | handle }}-{{ product.id }}" style="background-image: url({{ value | handle | append: '.' | append: file_extension | asset_img_url: '50x' }}); background-color: {{ value | split: ' ' | last | handle }};">
<span class="crossed-out"></span>
</label>
{% else %}
<label for="swatch-{{ option_index }}-{{ value | handle }}-{{ product.id }}">
{{ value }}
<span class="crossed-out"></span>
</label>
{% endif %}
</div>
{% endunless %}
{% endif %}
{% endfor %}
</div>
It seems you're looking for the Linked Options functionality.
Have a look at this doc:
https://help.shopify.com/themes/customization/navigation/link-product-options-in-menus
The code is hosted on GitHub:
https://gist.github.com/carolineschnapp/1083007
It's adjusted to work with swatches as well (I suppose you're using the default implementation).
Edit your product-swatch.liquid file under "snippets" folder.
Find {% for variant in product.variants %} and Put {% if variant.available %} right after it.
Find {% endfor %} and Put {% endif %} right before it.
If its not working, share the codes of product-swatch.liquid with us.