I am attempting to create a quick add button to a product on a custom page template using Shopify liquid. The product has several variants and I would like to assign a specific variant to this product; Namely the second variant.
For the sake of example, let's say my variant ID would be 456. So, basically, I want to be able to display the product with an id of 123, shown below. And I want the quick add to be assigned to the variant id 456. Is there a way to do this using the variant ID? Below is a sample of my loop.
Any help would be appreciated!
{%- assign my_products = collections['collection-handle'] -%}
{%- for product in my_products.products -%}
{%- if product.id == 123 -%}
{%- assign product_form_id = 'quick-add-' | append: section_id | append: product.id -%}
{%- if product.variants.size > 1 -%}
{%- form 'product', product, id: product_form_id, class: 'actions__form', novalidate: 'novalidate', data-type: 'add-to-cart-form' -%}
<input type="hidden" name="id" value="{{ product.selected_or_first_available_variant.id }}" disabled />
<button
id="{{ product_form_id }}-submit"
type="submit"
name="add"
class="add__button"
data-variant_id="{{ product.selected_or_first_available_variant.id }}"
aria-label="Add to cart - {{ product.title | escape }}"
>
<span>Add</span>
</button>
{%- endform -%}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
inside your product loop you can get variant like this and filter variant according to their variant id or tags.
{% for variant in product.variants %}
{% if variant.id == 456 %}
{% else %}
{% endif %}
{% endfor %}
Related
I'm trying to add "Customers also bought" section under the added items in the cart drawer. I'm doing that by checking for the tags that start with '__with', then getting their handle Now some tag products are duplicates of the ones already in the cart. How to remove duplicates?
I added this logic inside the cart-drawer.liquid.
<div class="CartAddons">
<div class="CartAddons__Heading">Customers also bought</div>
{%- for item in cart.items -%}
{%- assign tags = item.product.tags | join ' ' -%}
{%- assign product_handle = tags | split: '__with:' | last -%}
{%- assign associated_product = all_products[product_handle] -%}
{%- if tags contains '__with' -%}
<div class="CartAddons__Section">
<div class="CartAddons__Item">
{% render 'product-item', product: associated_product, use_horizontal: true, show_labels: false, show_product_info: true, show_vendor: false, show_price_on_hover: true %}
</div>
</div>
{%- endif -%}
{%- endfor -%}
</div>
Need to develop such logic to check if a product is already in the cart.
{% assign productsInCart = cart.items | map: 'product_id' %}
and then make sure the tagged product is not into the cart items array
{% untill productsInCart contains associated_product.id %}{% endunless %}
I am working a shopify shop but not trying to sell products but rather appointments.
I am using a shopify extension called Sesami to do so.
In the customer/account.liquid page I want to show the next coming appointment (or appointments) and a different information to people who don't have any future appointment coming.
I have been trying to do this with the following code :
{% if customer.orders != blank %}
{% for order in customer.orders %}
{%- for line_item in order.line_items -%}
{% for property in line_item.properties limit:1 %}
{% assign today_date = 'now' | date: '%s' %}
{% assign pre_date = property.last | date: '%s' %}
{% if pre_date >= today_date %}
{{ line_item.product.title | link_to: line_item.product.url }}
{% for property in line_item.properties limit:1 %}
{% if property != blank %}
{{ property.last | date: format: 'abbreviated_date' }}
{{ 'customer.orders.at' | t }}
{% endif %}
{%- endfor -%}
{% for property in line_item.properties offset:1 %}
{{ property.last }}
{%- endfor -%}
{{ line_item.image | img_url: 'small' | img_tag }}
{{ order.fulfillment_status_label }}
{% endif %}
{% endfor %}
{%- endfor -%}
{% endfor %}
{% else %}
Content for people with no booking at all
{% endif %}
But the problem is that the forloop stays open and therefore shows the content I am hoping to display to people with no upcoming appointment multiple times based on the total number of past appointments.
I imagine there is a much simpler way to do this and am hoping you can help me find it !
Thanks a lot,
Julien
Consider using {% break %} when you'd like the loop to stop it's current iteration.
https://shopify.github.io/liquid/tags/iteration/#break
I'm using Shopify and am trying to add the options to add gift wrap and a carry case to products being bought.
I can use the item.properties to ask the user for the choice and show that in the cart.
I now want to add an additional product to the cart if item.properties is set to "gift wrap" or "carry case".
This code is placed in the product-template.liquid but does not work:
{% for property in item.properties %}
{% if property.last == "Gift Wrap" %}
<p>This would add gift wrap.</p>
<script>
jQuery.post('/cart/update.js', {
updates: {
32005672697928: 1
}
});
</script>
{% endif %}
{% if property.last == "Carry Strap" %}
<p>This would add carry strap.</p>
{% endif %}
{% endfor %}
{% endunless %}
Doesn't seem the code you have was intended to be used on the product page. It looks like it should be placed on the cart page within the {% for item in cart.items %} ... {% endfor %} loop.
Also, this code will add only 1 wrap product, even if customers add 2+ wrapped items. I would change the code to something like the below:
{%- assign numWrappedItems = 0 -%}
{%- for item in cart.items -%}
{%- for property in item.properties -%}
{%- if property.last == "Gift Wrap" -%}
{%- assign numWrappedItems = numWrappedItems | plus: item.quantity -%}
{%- break -%}
{%- endif -%}
{%- endfor -%}
...
{%- endfor -%}
{%- if numWrappedItems > 0 -%}
<script>
jQuery.post('/cart/update.js', {
updates: {
32005672697928: {{ numWrappedItems }}
}
});
</script>
I hope the above makes sense.
I'm trying to iterate over items in the shopping cart and generate an upsell div with products NOT in the cart. Below is the code I have so far, but I run into issues when adding two items to cart running the loop twice generating the html twice. Any ideas on how to resolve it? I'm stumped.
{% for item in cart.items %} // iterates over items in cart
{% if item.product.id == 4456879040188 %} // checks if product id matches in item in cart
<div class="upsell-pop" style="text-align:center; width: 100%;">
<h4>Frequently bought together</h4>
{% for prod in collections.upsell.products %} // iterates products in collection upsell
{% unless prod.handle contains "product-name" %} // shows only prods that do not contain url handle
<div>
<span class="upsell-title">{{ prod.title }}</span>
<span class="upsell-price">{{ prod.metafields["meta"]["promo"] }} {{ prod.price | money }}</span>
<img src="{{ prod.featured_image | img_url: '200x' }}" />
<a class="btn-product" href="{{prod.url}}">View Product</a>
</div>
{% endunless %}
{% endfor %}
</div>
{% endif %}
{% endfor %}
Another thought is to somehow check to see if product is NOT in cart items inside to replace the existing "unless" statement, but not sure how to code it.
{% unless cart.items exist then %} // I know this is not correct syntax
<div>
<span class="upsell-title">{{ prod.title }}</span>
<span class="upsell-price">{{ prod.metafields["meta"]["promo"] }} {{ prod.price | money }}</span>
<img src="{{ prod.featured_image | img_url: '200x' }}" />
<a class="btn-product" href="{{prod.url}}">View Product</a>
</div>
{% endunless %}
On my mind, there are two steps here.
First, capture your cart content to get string to compare to when you loop through your upsell collection. This could be something like that:
{%- capture cart_items -%}
{% for item in cart.items %}
{{ item.product.handle }}{% unless forloop.last %} , {% endunless %}
{% endfor %}
{%- endcapture -%}
Then loop through your collection while checking your string does not contain the handle of the current product at each iteration:
{% for product in collections['upsell'].products %}
{% unless cart_items contains product.handle %}
{{ product.title }}
{% endunless %}
{% endfor %}
Remarks:
Snippet 1 => In line_item (here called item because it's shorter to write) object you may access product object attributes: item.product.product_attr_needed
Snippet 2 => To access directly a collection object using its handle you must use collections + square brackets containing collection handle + attribute. Here 'upsell' is the handle of your upsell collection.
Not tested but this should work.
HTH
{% assign leg = {{Predept.legs}} %}
{% for legs in {{leg}} %}
{% if {{leg[forloop.index0].direction}} == 'R' %}
{{leg[forloop.index0].arr_station_name}}
{%endif %}
{%endfor %}
I want to put the output of this for loop into another array. Any ideas?
Welcome, Jeet!
First, you don't ever nest the Liquid tags. Your basic loop should look something like this:
{% assign legs = Predept.legs %}
{% for leg in legs %}
<!-- Cool code & stuff here! -->
{% endfor %}
Now, in Liquid you can only create a new array by using the split filter on a string. We can also create a string by wrapping other commands with the capture tag. Putting that together, we get something like:
{% capture leg_data %}
{% assign legs = Predept.legs %}
{% for leg in legs %}
{% if leg.direction == 'R' %}
{% comment %}Output delimiter if needed {% endcomment %}
{% unless found_one %},{% endunless %}
{% assign found_one = true %}
{{ leg.arr_station_name }}
{% endif %}
{% endfor %}
{% endcapture %}
{% assign leg_data = leg_data | split: ',' %}
That will give us an array of all of our arr_station_name for the desired legs, but you may note that capture is also capturing all of the whitespace in there as well. If we need to prevent that from getting into our nice little array, we can use the whitespace-stripping - character on our tags to control that, giving:
{%- capture leg_data -%}
{%- assign legs = Predept.legs -%}
{%- for leg in legs -%}
{%- if leg.direction == 'R' -%}
{%- comment -%}Output delimiter if needed {%- endcomment -%}
{%- unless found_one -%},{%- endunless -%}
{%- assign found_one = true -%}
{{- leg.arr_station_name -}}
{%- endif -%}
{%- endfor -%}
{%- endcapture -%}
{%- assign leg_data = leg_data | split: ',' -%}
Hope this helps!