How to Display a Metafield in Shopify - shopify

We have a group of products that we want to have FREE Shipping. In order to do so, I have made their weight =0 and created a weight based shipping for 0lbs.
That way the shipping passes through the cart. But...I would like to display the actual weight on the product page.
I have created a metafield for the shipping weight, and I am trying to call that value to the product page, but not having any luck......
Here is what I am trying for code....
//------SHIPPING WEIGHT-------------------------//
{% if product.vendor == 'American Chains' %}
$('.wt').text((variant.ShippingWeight)+'lb');
// {{ variant.metafields.ShippingWeight.shipping_weight }}
{% else %}
$('.wt').text(parseInt(variant.weight * 0.0022046, 10) + 'lb');
{% endif %}
//------SHIPPING WEIGHT-------------------------//
Thanks for any help or direction on this one.

In Product.liquid you only have access to the Product. If you want to access a specific Product Variant you have to loop through the Product Variants. Within the loop you have access to the metafields for a variant.
{% for variant in product.variants %}
// to display the variant metafields use {{resource.metafields.namespace.key}}
{{ variant.metafields.ShippingWeight.shipping_weight }}
{% endfor %}

http://docs.shopify.com/themes/liquid-documentation/objects/metafield
go threw with this link
simple...
{% for field in product.metafields.instructions %}
{{ field | first }}: {{ field | last }}
{% endfor %}

Meta fields are created by using ( metafields or shopify FD ) shopify app for products edit page
Then enter the following values in form fields (Namespace,Key,Value)
After entering values,you can retrive values like following code..,
Namespace = metafield_values,
Key= color,
Value= red,
{% assign value = product.metafields.metafield_values%}
<p>{{ value.color }}</p>
output: red

------------------------------
{{metafields.namespace.key}}
------------------------------
Namespace = prod_video,
{{ product.metafields.prod_video.prod_video }}
{{ collection.metafields.prod_video.prod_video }}
---------metafield loop with same namespace & different key------------
<div class="prod_add_img">
{% for collection in product.collections %}
{% for field in collection.metafields.additional_images %}
<img src="{{ field | last | asset_url }}">
{% endfor %}
{% endfor %}
</div>

In metafield section, shopify show's shortcode. For below screenshot the code is
{{product.metafields.custom.theme_color}}

Related

How to display different variant prices to different customers? (Shopify/Liquid)

I'm currently working on the shopify site for the B2B company where i work.
(Yeah, we know that Shopify Plus is the best option for B2Bs, but we can't afford the price)
We work on two different customer lists and really need two different prices to show to customers on the main-product page.
I managed the lists with customer tags, and also the two different prices with Variants.
Now i was trying to figure out how to show the Price of the Variant 1 to customers with the "list1" tag and the Price of the Variant 2 to customers with the "list2" tag.
(Yeah, we know that there are Wholesale Pricing app to do this, but we can't afford the monthly cost either).
I tried something like this, but i'm stuck...
Could you please help me out?
This is my last try:
{% if customer.tags contains "list1" %}
{% assign current = product.selected_or_first_available_variant %}
{%- assign target_variant = product.variants[0] -%}
<div class="no-js-hidden" id="variantPrice-{{ section.id }}" role="status" {{ block.shopify_attributes }}>
{%- render 'price', product: product, use_variant: true, show_badges: true, price_class: 'price--large' -%} </div>
{% else %}
{% assign current = product.selected_or_first_available_variant %}
{%- assign target_variant = product.variants[1] -%}
<div class="no-js-hidden" id="variantPrice-{{ section.id }}" role="status" {{ block.shopify_attributes }}>
{%- render 'price', product: product, use_variant: true, show_badges: true, price_class: 'price--large' -%} </div>
{% endif %}
I somehow managed to solve this. After being stuck on it for two days :P
It works with something like this:
{%- when 'price' -%}
{% if customer %}//Hide the price if not registered - endif is at the end//
{% if customer.tags contains "list1" %}
{%- assign target_variant = product.variants[0] -%}
<div class="no-js-hidden" id="price-{{ section.id }}" role="status"
{{block.shopify_attributes }}>
{%- render 'price', product: product, use_variant: true, show_badges: true,
price_class: 'price--large' -%} </div> //It shows the price of the First Variant//
{% else %}
{%- assign target_variant = product.variants[1] -%}//I can't figure out if this is relevant for the code, but it works like this, so...//
<div id="variantPrice" role="status" {{ block.shopify_attributes }}>{%- render 'price' -%} </div> //It shows the price of the Second Variant //
{% endif %}
I don't know if this is the correct way, but it works, so it's fine :P
Hope it will help someone with the same issue.
The interesting thing about your approach here is that a customer from List type 1 would be seeing the price for the variant as List type 1 price, but there is zero stopping them from simply placing the variant with the different price from List type 2 in the cart if they wanted.
In other words, you are decorating the price displayed, which is your goal I guess, but there is no actual logic in place to ensure customers pay the correct amount. For that, you would need a different logic, one that tries hard to ensure a customer from List type 1 only gets to checkout with product variants that are assigned to List type 1. Without that logic, you're wide open to a bit of price abuse.
The approach may be very straight to the point:
{% if customer %}
{% for variant in product.variants %}
{% assign current = forloop.index | plus: 1 | prepend:'list' %}
{% if customer.tags contains current %}
{{ variant.price}}
{% assign found = true %}
{% endif %}
{% endfor %}
{% unless found %}
Display what you want to if no price has been found for logged in user
{% endunless %}
{% else %}
What you want to display when customer is not connected to an account.
{% endif %}
You may use the same logic for your add to cart form.

Can I Add Discount Code To Metafield And Include In Add To Cart Button to auto apply to checkout page?

I have created a new product metafield: product.metafields.my_fields.discount_code
In my product-template.liquid, there is this section:
<button class="btn cv_addtocart{% if section.settings.enable_payment_button %} btn--secondary{% else %} btn--primary{% endif %}" type="button" name="add" data-add-to-cart {% unless current_variant.available %}disabled="disabled"{% endunless %}>
<span data-add-to-cart-text>
{% if current_variant.available %}
{{ 'products.product.add_to_cart' | t }}
{% else %}
{{ 'products.product.sold_out' | t }}
{% endif %}
</span>
</button>
{% if section.settings.enable_payment_button %}
{{ form | payment_button }}
{% endif %}
</div>
</div>
I am trying to pass the value of a metafield for a product into the add to cart button. In this case, I want the discount code which is entered into the product metafield to be included.
So am hoping to do something like this:
{% if section.settings.enable_payment_button %}
{{ form | payment_button | discountCode = product.metafields.my_fields.discount_code }}
{% endif %}
Basically, I am trying to automatically apply a normal discount to a product at checkout. I have seen the various shareable links that append the discount code to the url, but this does not suit my needs. Instead, I would like to retrieve the discount code (DISCOUNT20) from a metafield for that product on the checkout page and apply the coupon code there.
Any thoughts? I have been stuck on this for a long time
So I have figured out a more reliable route:
I located my cart template liquid file and searched for a form
<form action="/cart" method="post" >
Directly below this line I inserted this
{%- for item in cart.items -%}
{%- if item.product.metafields.my_fields.discount_code.value != blank -%}
<input type="hidden" name="discount" value="{{item.product.metafields.my_fields.discount_code.value}}" >
{%- endif -%}
{%- endfor -%}
In my case, value = an interpolated value being retrieved from a product metafield for the product in the cart.
FYI - you need to create a metafield in settings, then create a discount code, copy the discount code, go to your product that you want the discount code to apply to, access the product and scroll down to metafields, paste the discount code in the product's discount(if you named your metafield "discount", you might have named it something else) metafield.
Hence, as the form will be submitted with a name="discount" and value="discount_code", the checkout page will evaluate to true for discount and use the appropriate values. However this is only possible with the for loop.
For such a simple fix, I am surprised it was so hard to figure out. Hope this helps you!
** Some extra reading if you want: https://wearetmbr.com/shopify-auto-fill-discount-code-on-checkout-page/ **

shopify custom liquid section show blank when added via theme editor into an existing page

I created a "custom liquid" section with following code
<ul>
{% for product_type in collection.all_types %}
<li class="{{ product_type | handleize }}">
{{ product_type | link_to_type }}
</li>
{% endfor %}
</ul>
It suppose to show a list of product type name as link. But I see nothing. However, when I simply add text into the "Custom Liquid" section, I see it in the page when I add the liquid custom section in the theme's visual editor.
I am using the Free OS2.0 theme
Any idea why?
The above code will only work on Collection page as it is based on collection object. Homepage and other product pages does not have access to collection object directly. However, you can use collections object to get a specific collection.
Show Type on Collection Page
{% for product_type in collection.all_types %}
{{ product_type | link_to_type }}
{% endfor %}
Show Type for all collections on any page
{% for collection in collections %}
{% for product_type in collection.all_types %}
{{ product_type | link_to_type }}
{% endfor %}
{% endfor %}
Show Type for specific collection on any page
{% for product_type in collections['collection-handle'].all_types %}
{{ product_type | link_to_type }}
{% endfor %}
Collection Object
Collections Object

Vendor list page - Only list vendors with items in stock

I have a page on my site that lists all the vendors in my shop like so:
<div class="vendor-list" id="designers-a-to-z">
<ul>
{% assign current = "" %}
{% capture alphabet %}
-A-B-C-D-E-F-G-H-I-J-K-L-M-N-O-P-Q-R-S-T-U-V-W-X-Y-Z
{% endcapture %}
{% assign letters = alphabet | split: '-' %}
{% assign its_a_letter = false %}
{% for vendor in shop.vendors %}
{% assign vendor_first_letter = vendor | strip | upcase | slice : 0 %}
{% for letter in letters %}
{% if vendor_first_letter == letter %}
{% assign its_a_letter = true %}
{% break %}
{% endif %}
{% endfor %}
{% if its_a_letter %}
{% unless vendor_first_letter == current %}
<h3><span class="anchor" id="designers-{{ vendor_first_letter }}"></span>{{ vendor_first_letter }}</h3>
{% endunless %}
<li class="vendor-list-item">
{{ vendor }}
</li>
{% else %}
{% assign vendor_first_letter = "#" %}
{% unless vendor_first_letter == current %}
<h3><span class="anchor" id="designers-{{ vendor_first_letter }}"></span>{{ vendor_first_letter }}</h3>
{% endunless %}
<li class="vendor-list-item">
{{ vendor }}
</li>
{% endif %}
{% assign current = vendor_first_letter %}
{% endfor %}
</ul>
</div>
Some of these vendors don't currently have any items in stock so it's pointless to have them show up here. Is it possible to display only the vendors that have items in stock within their collection?
I currently have 2 collection tags in my store for 'in-stock' and 'sold-out' to help filter them with our filter menu and that is appended to the url so we only show customers in stock items.
Since a product has a vendor, and a product has inventory, you could just check that way. It would be insanely slow and obnoxious but hey! That is what a hosted platform is for, to turn crazy Liquid into the right tight HTML.
Note the Liquid for product.available
Returns true if a product is available for purchase. Returns false if all of the products variants' inventory_quantity values are zero or less, and their inventory_policy is not set to "Allow users to purchase this item, even if it is no longer in stock."
So while you loop through your vendor list, loop through all the products, checking the product vendor for a match, and the availability. If they don't suit you... skip the vendor.
Would be interesting to see how slow this is... but you never know till you try...
Another approach, perhaps smarter, is to iterate all your in-stock products once. Build your vendor list out of that, instead of shop.vendors.
I was able to get this working by writing it like this:
{% for vendor in shop.vendors %}
{% for collection in collections %}
{% if collection.title == vendor %}
{% if collection.all_tags contains 'in-stock' %}
then the conditions for checking the first letter and displaying the vendor, etc. nothing new
It only worked, however, on my dev site that I was testing it on and when I pushed it to production I got liquid error: memory limits exceeded. My dev site is definitely lacking in collections and products compared to my live site so this may work for people who have smaller sites.

Shopify If in collection then display this

I am trying to write a simple if statement, but always struggle with shopify's system.
Essentially I want it to do this:
{% if collection.product == 'discontinued' %}
This Product is Discontinued.
{% endif %}
If it's in this collection, then display this text/html. Otherwise it wouldn't display anything. This would be in the product.liquid template.
Any ideas?
This is what ended up working:
{% for c in product.collections %}
{% if c.handle == "discontinued" %}
This product is Discontinued
{% endif %}
{% endfor %}
You can create an array of the collections for a product using map on product.collections. This which will create a new array with your specified property, i.e. the handles of each collection.
You can then check if this new array contains the handle you want to work with.
{% assign productCollections = product.collections | map: "handle" %}
{% if productCollections contains 'your-collection-handle' %}
{% comment %} DoSomething {% endcomment %}
{% endif %}
So for your example:
{% assign productCollections = product.collections | map: "handle" %}
{% if productCollections contains 'discontinued' %}
This product is Discontinued
{% endif %}
You can map other fields if your case is different, such as the title.
I guess this will help any one, I have used in the sidebar of shopify website.
The current collection page will get checked by this below code.
<div class="row-fluid not-animated" data-animate="fadeInUp">
<div class="title">By Collections</div>
<form class="coll">
{% assign col_tags = collection.title %}
{% for collection in collections %}
<input type="radio" value="{{ collection.url }}" name="collections" {% if col_tags contains collection.title %} checked {% endif %} >{{ collection.title | escape }} <br/>
{% endfor %}
</form>
If I understand how liquid collections work in Shopify, you will need to iterate over all of your products.
You'd need to do something similar to this if you are working with collections directly:
{% for product in collection.product %}
{% if product.tags contains 'discontinued' %}
This product has been discontinued :(
{% endif %}
{% endfor %}
If you are just working with a single product you can probably just use the inner if liquid tag part.
References:
Collection.liquid
Product.liquid
You can indeed add discontinued products to a collection called discontinued.
When rendering a product, you could do as csaunders suggests, simply loop through all the products in the discontinued collection, and check if the id of the current product matches any of the products in that collection. If so, do what you must do. No need to use tags.