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

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.

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 to only display the available product variant prices in the products overview

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

Hiding products based on customer tag Shopify search.liquid

I hope someone may be able to help with this.
I am currently setting up my store with shopify and have duplicated my products for retail and wholesale customers.
The only issue I am faced with is that the retail products are still showing when a customer with the 'wholesale' tag uses the search box.
I was wondering if I add a 'retail' tag to the relevant products, can add any code in search.liquid so that if the customer.tag contains 'wholesale' do not show products with product.tags 'retail' or something along those lines?
My current search.liquid looks like:
<!-- /templates/search.liquid -->
{% comment %}
To return only products or pages in results:
- http://docs.shopify.com/manual/configuration/store-customization/return-only-product-in-storefront-search-results
- Or manually add type=product or type=page to the search URL as a parameter
{% endcomment %}
{% comment %}
Check to enforce respond.js
{% endcomment %}
{% assign respond_js_secret_key = shop.domain | md5 %}
{% unless search.terms == respond_js_secret_key %}
{% comment %}
Avoid accessing search.results before the opening paginate tag.
If you do, the pagination of results will be broken.
{% endcomment %}
{% paginate search.results by 12 %}
<div class="grid">
<div class="grid__item">
<header class="section-header text-center">
{% if search.performed %}
{% if search.results_count == 0 %}
<h1 class="text-center">{{ 'general.search.no_results_html' | t: terms: search.terms }}</h1>
{% else %}
<h1 class="text-center">{{ 'general.search.results_for_html' | t: terms: search.terms }}</h1>
{% endif %}
{% else %}
<h1 class="text-center">{{ 'general.search.title' | t }}</h1>
{% endif %}
<hr class="hr--small">
</header>
{% include 'search-bar', search_btn_style: 'btn', search_bar_location: 'search-bar--page' %}
{% if search.performed %}
<hr class="hr--medium hr--clear">
<div class="grid-uniform">
{% for item in search.results %}
{% assign itemIswholesale = false %}
{% if item.tags contains 'wholesale' or item.title contains 'wholesale' %}
{% assign itemIswholesale = true %}
{% endif %}
{% if itemIswholesale and customer and customer.tags contains 'wholesale' %}
{% if item.object_type == 'product' %}
{% assign product = item %}
{% include 'product-grid-item' %}
{% else %}
<div>
<div>
<a href="{{ item.url }}">
<span>
<span>{{ item.title }}</span>
{{ item.content | strip_html | truncatewords: 60 }}
</span>
</a>
</div>
</div>
{% endif %}
{% else %}
{% unless itemIswholesale %}
{% if item.object_type == 'product' %}
{% assign product = item %}
{% include 'product-grid-item' %}
{% else %}
<div>
<div>
<a href="{{ item.url }}">
<span>
<span>{{ item.title }}</span>
{{ item.content | strip_html | truncatewords: 60 }}
</span>
</a>
</div>
</div>
{% endif %}
{% endunless %}
{% endif %}
{% endfor %}
</div>
{% if paginate.pages > 1 %}
{% include 'pagination' %}
{% endif %}
{% endif %}
</div>
</div>
{% endpaginate %}
{% else %}
{% include 'respond' %}
{% layout none %}
{% endunless %}
I am a complete novice and have managed to get by this far following help and tutorials online so any help would be very much appreciated.
I can't afford to subscribe to an additional app at present, such as locksmith and would really like to keep control so I can continue administration in future,
Thanks in advance,
You may try doing something like that inside the
{% if search.performed %}
condition.
First get some information about user and store it:
{% assign wholesale = false %}
{% if customer %}
{% assign customer_tags = customer.tags | split: "," %}
{% if customer_tags contains 'wholesale' %}
{% assign wholesale = true %}
{% endif %}
{% endif %}
Explanations : first you assign a false statement to the wholesale status. Then you check if it is customer ( no need to go further if user is not connected). If he is, then you check if he has a wholesale tag. If he is you assign a true statement.
Then you are able to display something different this way:
{% for result in search.results %}
{% if wholesale %}
Do something
{% else %}
Do something else
{% endif %}
{% endfor %}
Please not that you may have some issues with pagination.

Shopify - How to exclude a collection in paginate?

I need to exclude a collection inside the paginate loop. But if I use the conditional statement, it will still be counted in paginate count.
So If I paginate by 10 and there are 2 products from the excluded collection in first page, I will only see 8 products in first page.
Any solution for this? Here's my snippet:
{% paginate collection.products by 10 %}
<ul>
{% for product in collection.products %}
<!-- Check for collection -->
{% assign is_treatment = false %}
{% for c in product.collections %}
{% if c.handle == "salon-treatment" %}
{% assign is_treatment = true %}
{% endif %}
{% endfor %}
{% unless is_treatment %}
<li>{{ product.title }}</li>
{% endunless %}
{% endfor %}
</ul>
{% endpaginate %}
Note: This question is duplicated from the one I posted in Shopify forum.
What I did for something like this was first load in all the desired products into a collection of my own (basically an array of objects), and then paginate THAT array... so, if you write a function called exclude_some_products which returns all the unexcluded products, do this:
{% assign my_smaller_collection = exclude_some_products collection %}
{% paginate my_smaller_collection.products by 10 %}
<ul>
{% for product in my_smaller_collection.products %}
<!-- Check for collection -->
{% assign is_treatment = false %}
{% for c in product.collections %}
{% if c.handle == "salon-treatment" %}
{% assign is_treatment = true %}
{% endif %}
{% endfor %}
{% unless is_treatment %}
<li>{{ product.title }}</li>
{% endunless %}
{% endfor %}
</ul>
{% endpaginate %}
p.s. pardon my code, I'm not even sure what language this is!

Display only certain Shopify line items

This is for a Shopify site. Is there a way to display only certain line item properties in the cart? I have several and it looks messy so only want to display a chosen two or three.
I am assuming you have set up your line item properties similar to how it suggests on the Shopify wiki (Line Item Properties).
You will have something like this in product.liquid:
<div>
<p><label for="property1">Property 1:</label></p>
<p><input type="text" id="property1" name="properties[Property1]" /></p>
</div>
Then put this code in cart.liquid, beneath the cart item's title:
{% for p in item.properties %}
{% if p.first == 'Property2' or p.first == 'Property5' %}
{% unless p.last == blank %}
{{ p.first }}:
{% if p.last contains '/uploads/' %}
<a class="lightbox" href="{{ p.last }}">{{ p.last | split: '/' | last }}</a>
{% else %}
{{ p.last }}
{% endif %}
<br />
{% endunless %}
{% endif %}
{% endfor %}
The code above is straight from the Line Item Properties article on the Shopify wiki (section 3.1 Displaying line item properties on the cart page). I've just added the if statement on the second line to only display the properties I want:
{% for p in item.properties %}
{% if p.first == 'Property2' or p.first == 'Property5' %}
...
{% endif %}
{% endfor %}
Or, if you want to display several properties in a row (e.g. the first 3 properties), you could do it like this (without the if statement):
{% for p in item.properties limit:3 %}
...
{% endfor %}