Liquid coding for disclaimer in cart field for any product containing product tag - input

I am currently using this code in the cart.liquid. I have tried it in the cart.template.liquid, but I need it to appear at the top of the cart container or near the products in the cart since the checkbox is required. I am new to coding, so please be specific. I used https://ui-elements-generator.myshopify.com/pages/cart-attribute to generate the required checkbox part. It said to insert it in the cart.liquid instead of the cart.template.liquid. Any advice would be awesome.
`{% for item in cart.items %}
{% if product.tag contains "delay" %}
<form>
<p class="cart-attribute__field">
<input type="hidden" name="attributes[I am aware that my order may have a 6 to 8-week
shipping delay, since there are higher than normal ordering volumes.]" value="No">
<input required class="required" type="checkbox" name="attributes[I am aware that my
order may have a 6 to 8-week shipping delay, since there are higher than normal ordering
volumes.]" value="Yes"{% if cart.attributes["I am aware that my order may have a 6 to 8-
week shipping delay, since there are higher than normal ordering volumes."] == "Yes" %}
checked{% endif %}>
<label>I am aware that my order may have a 6 to 8-week shipping delay, since there are
higher than normal ordering volumes.</label>
</p><br>Not interested in waiting, check out alternative options for immediate shipping.
<b><i>SHOP NOW</i></b>
</form>
{% endif %}
{% endfor %}`

What theme are you using?
On newer themes the main cart content is in the cart.template.liquid file so you are in the right place.
The issue here is using {% if product.tag contains "delay" %} since the product object is not available. Instead, since you are looping through the cart items, the code should be:
{% if item.product.tags contains "delay" %}
What is happening here is the item variable is used to loop through all the cart line items. Using this you are then able to access the product.tags - note that it is "tags" as opposed to "tag" since it is an array of all the tags. More info on that can be seen here.
Hope that helps!

Related

How can I display specific Collection on a product or list page

I have a shopify store with new, used and refurbished amplifiers & speakers.
This condition is stored in a manual collection (four of them). The others collections being automated.
I would like to display the condition of the product on the product page or the products list.
So basically I need to get all the collections and filter to display one of the four :
If the product belongs to collection "used" display collection "used"
If the product belongs to collection "new" display collection "new"
etc...
The closest to what I want to do has been made trough this code :
{% assign product_collection = product.collections.first %}
{% if product_collection %}
This product is part of my {{ product_collection.title | link_to: product_collection.url }} Collection
{% endif %}
Found here : https://community.shopify.com/c/Shopify-Design/RESOLVED-Display-Collection-on-Product-Page/td-p/230899
With this I am not able to filter on the four collections.
I have spent the day on this...If somebody can help, that would save my day :)
You can add all collections(title or handle value) on the product-grid-item.liquid.
<div class= "grid-item
{% for product_collection in product.collections %}
{{product_collection.title | handle }}
{% endfor %}
">
...
</div>
And then you can filter them with JavaScript on the frontend.
Hope this could help you

Show products on article

How can I show a list of products (like a recipe) on a article page.
Can you give me some guidance on what should i use to achieve that behavior?
How can i link those products dynamically to the article?
Getting the products once we know what they are
There are two ways to bring up products on an arbitrary page in Shopify:
1) Using all_products[handle]
Using the product handle to get the product from the all_products global object.
Example:
{% assign ingredient = all_products['lavender-oil'] %}
This works well for small numbers of products, but for large numbers of products it may cause delays in page-loading times. We are also limited to only 20 (I think) calls to all_products per page, so this wouldn't work for recipes with a ton of ingredients in them.
2) Using a collection
Use a collection that contains only the products required. You can reference any arbitrary collection if you know the collection's handle. When making collections, you can also sort products manually to control the order that they appear in when you loop through it. Collections can contain an arbitrary number of products, and I believe the default pagination will give you is either the first 20 or 50 products if you don't specify any other limit. If required you can adjust the number of products served to as high as 1000 by wrapping your collection-product loop with paginate tags (though that upper limit is definitely not recommended for performance reasons)
Example:
{% assign ingredients = collections['love-potion-number-9'] %}
{% for product in ingredients.products %}
<h2>{{ product.name }}!!</h2>
{% endfor %}
The downside for both of these is that you can't write Liquid code inside your article content in Shopify, so this ingredients section would need to be written as a snippet or a section in your theme files and included in your article template used for these recipes.
This leads me to consider the next issue - you would want to include a concept of quantity with the ingredients, and so far neither of the above give us that. So now, the hard part:
Getting that information into a Liquid snippet/section in the first place
There are a few different ways that I can think of offhand that would help you out here. No one is perfect, unfortunately.
Using Metafields
Metafields are a great tool available in Shopify, but unfortunately Shopify doesn't make them easy to use [1].
Once you have a metafield-editing tool, come up with a naming structure for the 'namespace' and 'key' values. For example, you might create the following metafields for the recipe you provided. (Note: How these would be entered will depend on what metafield-editing tool you're using)
namespace: 'ingredients', // We'll use this as the 'box' that holds all our ingredients
key: 'juniper-berry-oil', // This will be the product handle for the product in question
value: '2 drops' // The quantity used for the recipe
namespace: 'ingredients',
key: 'rosemary-ct-camphor-oil',
value: '1 drop'
namespace: 'ingredients',
key: 'cypress-oil',
value: '1 drop'
... (etc) ...
Then, in your theme file where you are creating your ingredient list, you would have code that looks something like this:
{% assign ingredients = article.metafields.ingredients %}
{% for ingredient in ingredients %}
{% assign handle = ingredient.first %}
{% assign amount = ingredient.last %}
{% assign product = all_products[handle] %}
<!-- HTML code here -->
{% endfor %}
Using Tags and Products
If you create a tag-naming scheme, you can loop through those and use them to build your ingredient list. For example, if you give the article a number of tags in the form ingredient_[product-handle]_[amount], you would be able to reference them as:
{% for tag in article.tags %}
{% if tag contains 'ingredient' %}
{% assign breakdown = tag | split: '_' %}
{% assign handle = breakdown[1] %}
{% assign product = all_products[handle] %}
{% assign amount = breakdown | last %}
<!-- HTML Code -->
{% endif %}
{% endfor %}
The downside to this method is that there's no easy way to reorder the tags if done this way - using a collection will give you better control of that.
Getting recipe amounts into a Collection loop
The easiest way to reference a collection would be to have a collection with the same handle as the article - then you can reference the collection and its products as:
{% assign ingredients = collections[article.handle] %}
{% for product in ingredients.products %}
<!-- HTML Code here -->
{% endfor %}
This has the advantage of letting you easily sort the ingredients by setting the collection to have a Manual sorting method, but the corresponding downside is that there's no obvious place to put the quantity information.
One way to get that information in would be to use either tags or metafields - metafields would have the advantage of being able to directly access the quantity for the product - if using the naming convention above in the metafields part of this answer, you could use:
{% assign ingredients = collections[article.handle] %}
{% for product in ingredients.products %}
{% assign amount = article.metafields.ingredients[product.handle] %}
<!-- HTML Code here -->
{% endfor %}
If using tags, you would need a format that could be split up like in the tag section and loop through all your tags each time to find the one for your product. If your tags were set up as ingredient_[product-handle]_[amount]
If using tags, you would need a format that could be split up like in the tag section and loop through all your tags each time to find the one for your product. If your tags were set up as the example above:
{% for tag in article.tags %}
{% if tag contains 'ingredient' and tag contains product.handle %}
{% assign amount = tag | split: '_' | last %}
{% endif %}
<!-- HTML Code -->
{% endfor %}
Hopefully this helps you get going!
[1] Using Metafields: There are several possible solutions for editing metafields in Shopify - my personal preference is the 'Shopify FD' extension for Chrome, but the recent updates to the Shopify admin screens are interfering with this extension's ability to load & show its metafield panels on some pages. I know that product pages still work, but some pages (like collections) don't anymore.
There are also a number of apps available for your store to edit metafields - I haven't used any of them, so I can't speak to their value, but you can view the list here: https://apps.shopify.com/search?q=metafield&st_source=
If you have a coding background, you can also create and update metafields yourself by sending the right data to Shopify's Admin API - see the documentation at https://help.shopify.com/en/api/reference/metafield if you want to try doing it yourself.
Here is a sure to succeed recipe. Write your Article. It will have a handle, unique to it. Save that in your head, clipboard, etc. Now create a manual collection. Give it the same handle. Now you can reference an empty collection by the Liquid:
collection['some-handle-to-an-article']
What if you now filled that collection with the products in your recipe? Eureka. Genial! You can then list them in a simple Liquid for next loop like this:
{% for product in collection['some-handle-to-an-article'] %}
{{ product.title }}
{% endfor %}
Or you could be a smarty pants and gather the handles of the products manually yourself. Store them in a metafield resource assigned to the article. For example, a string like 'a-blah,b-blahblah,c-zigo-von-goober' and then use Liquid to find that metafield in the article template. Split that string by commas. Now use the most excellent all_products like this:
{% assign fizzbuzz = all_products['a-blah'] %}
{{ fizzbuzz.title }}
And there are many more creative options. Shopify Liquid is ripe for play like this. No limits, except on all_products at 20... you cannot go more than that.

Shopify liquid : cart-template variant is not defined

I am simply allowing to checkout out of stock product to buy. When a customer wants to buy product has inventory less than zero and clicks on view cart from ajax cart, I simply want to show message " dispatch by 7 June." in cart-template.liquid.I have applied logic as given below. If required full code ready to share.
{% if variant.inventory_quantity < 1%}
<p id="dispatch" style="color: #f48c21">Will be dispatched by June 7</p>
{{variant.inventory_quantity}}
{% endif %}
<script>console.log(variant.inventory_quantity)</script>
when I print the message in cart-template.liquid without if condition I can see this message. I found that it does not print anything inside {{}} also checked with console.log gives error as variant is not defined My query Is do I need to define variant manually? if yes how? or need to use a different liquid variable to check inventory quantity of product less than zero?
Let me know if any more are required. Thanks.
I have started printing all variant variable. I just simply added item before variant.inventory_quantity and it saves my day.
{% if item.variant.inventory_quantity < 1 %}
<p id="dispatch" style="color: #f48c21">Will be dispatched by June 7</p>
{% endif %}

Unless Clause Leaving Blank Space in Collection Page

I asked about including a where clause in the collections page the other day but decided to scrap going that route. I'm now just using unless logic in the page. This route has worked except for one tiny flaw. When I include the unless clause in the collection.liquid page, the grid still leaves an empty space where the product that's being ignored would normally sit, and also including it in the count. How can I get this space to go away and how can I get it to not include it in the product count? It seems like the unless clause is just keeping it from appearing, not truly excluding it.
Here is the code:
<div class="{% if settings.show_collection_sidebar %}desktop-10{% else
%}desktop-12{% endif %} tablet-6 mobile-3" id="bside">
<div id="product-loop">
{% for product in collection.products %}
{% unless product.title contains "Sampler" %}
<div class="product {% if settings.products_per_row == '3'
%}desktop-4{% cycle ' first', '', ' last' %}{% elsif
settings.products_per_row == '4' %}desktop-3{% cycle ' first',
'', '', ' last' %}{% endif %} tablet-half mobile-half" id="prod-
{{ product.id }}" data-alpha="{{ product.title }}" data-price="
{{ product.price }}">
{% include 'product-listing' %}
</div>
{% endunless %}
{% endfor %}
</div>
</div>
I've tried moving around where the unless code is, outside the for loop, outside the product loop, but nothing has worked.
Thanks,
RDV
What you've written should be working - I would check your product-listing snippet for anything referencing forloop.index, since the index is a variable that will be incremented even if you're not doing anything on that iteration.
For cleanliness in the liquid code, I usually use the continue statement so that I'm not wrapping potentially huge blocks of code with liquid tags - I find that it gets hard enough to keep track of all the openings/closings in liquid if I'm doing moderately complex stuff otherwise. So with this example, instead of using unless you could consider {% if product.title contains 'Sampler' %}{% continue %}{% endif %}
But all of this is ignoring the most powerful tool that we have at our disposal - making sure the collection only contains the right products in the first place!
I'm assuming that you're looking at your "All Products" collection with this code. By default, there's an invisible collection in your store called "All" that, true to its name, contains every product visible in the online store. However, you can override this by making your own collection named 'All' (specifically, with a handle of 'all' - the actual title doesn't matter as long as this is the handle). If you want "All" to mean "Everything that's not a sampler", just make a "Smart Collection" with the condition "Product title DOES NOT CONTAIN 'Sample'" - and voilĂ ! There's nothing to skip and the total count will always be correct!

Shopify - hidden properties['...'] in /cart/add form are visible in shopping cart

Inside <form action="/cart/add"> I am using
<input type="hidden" name="properties[myId]" />
to add some technical ID's to the product which I then read using a hook when the product is purchased. It is all working fine except that my hidden inputs are visible in the cart (and it doesn't look very good). Is there a way to add properties which do not appear in the product description in the shopping cart but are still part of the item properties?
Placing an underscore at the beginning of the name hides the property: <input type="hidden" name="properties[_myId]" />
https://help.shopify.com/themes/customization/products/get-customization-information-for-products#hide-line-item-properties
Note: while this is true for most themes I have seen some themes where this is not respected... to be used with caution.
Add them to cart attributes. Use attributes[myId] instead of properties[myId]
More details - Get more information on your cart page with cart attributes
EDIT: This answer is wrong. As Francois' answer has shown, it is possible to have hidden properties without making the merchant edit their liquid code.
If you look at your "cart.liquid", there should be some code in there like this:
{% for p in item.properties %}
...
{% endfor %}
If you want to store some information in a line item's properties without it being visible on the cart page, you need to edit the liquid code to keep it from being output. One way to do this is to remember the names of the properties that need to be hidden, and stop them from being output with an if or unless:
{% for p in item.properties %}
{% unless p.first == 'hidden_prop_1' or p.first == 'hidden_prop_2' %}
...
{% endunless %}
{% endfor %}