IF condition for schema pages without variants - shopify

So I am trying to solve a bad Schema implementation and I am not very familiar with Liquid. I got the Schema to work on the variant URL as it was not correct and giving a 404 but now the products without variants are getting flagged.
{%- if variant.sku != blank -%}
"sku": {{ variant.sku | json }},
{%- endif -%}
"url": {{ request.path }}{{ variant.url}}
}{% unless forloop.last %},{% endunless %}
{%- endfor -%}
enter image description here
So I want something to pull the variant URL but when they're not a variant URL it should not generate by itself.
Looking forward to hearing from you folks!
I was not expecting it to pull variant URLs on products where there is none but I guess this is what the code says so it is expected.

Related

Change the h1 of featured product.liquid

I am working with a page that has multiple h1's, the reason is becuase feature products have a h1 in their title.
This is what's inside featured-product.liquid, the rest is schema
{%- if section.settings.divider -%}<div class="section--divider">{%- endif -%}
{%- assign product = all_products[section.settings.featured_product] -%}
{%- if product != blank -%}
{%- render 'product-template',
product: product,
section_id: section.id,
blocks: section.blocks,
image_position: section.settings.image_position,
image_container_width: section.settings.image_size,
product_zoom_enable: section.settings.product_zoom_enable,
sku_enable: section.settings.sku_enable,
thumbnail_position: section.settings.thumbnail_position,
thumbnail_arrows: section.settings.thumbnail_arrows,
mobile_layout: section.settings.mobile_layout,
video_looping: section.settings.enable_video_looping,
video_style: section.settings.product_video_style,
is_recommendation: true
-%}
{%- endif -%}
It seems that I am simply telling the code what information to take, but how can I make that only in this area the title has a h2? I have been researching for hours on this topic, but I can't find much information.
I am working with the impulse template
inside featured-product.liquid you see the code of:
{%- render 'product-template',
......
-%}
which is referring that you are including a snippet called 'product-template' so on folder snippets you will find a file called product-template.liquid, open that file, and you will find the <h1> you can change it to <h2> if you want
if you want to keep product-template.liquid to keep using <h1>on some other places, then:
Duplicate this snippet product-template.liquid to make new-product-template.liquid and on the new-product-template.liquid change the <h1> to <h2>
Inside featured-product.liquid use the duplicated snippet new-product-template.liquid so it will be: {%- render 'new-product-template', ..... -%}

checking for inventory quantity in mini cart page Shopify

I am developing a shopify theme, i have created mini cart page as shown in this image, my website is: https://codeinspire-dev2.myshopify.com/cart
I am using vue.js for controling this mini cart page data, i have called 
axios.get('/cart.js') for populating it with data, that call gives me cart object with all items on it, but there is no 
inventory_quantity property there. User can change quantity on mini cart page, but  i can't check if the product quantity on mini cart page gets bigger then it's inventory_quantity. How can i do that. Any help is appreciated.
You have two options.
Option 1.
As cart JSON object doesn't provide information about variant inventory quantity available, you need to create such an object manually in the theme template. See the code below that will give you an idea how to get inventory quantity available for the items in your cart:
{%- assign cart_items_count = cart.items | size -%}
var cartItemMaxQuantities = {
{%- for item in cart.items -%}
"{{ item.id }}": {{- item.variant.inventory_quantity -}}
{%- unless forloop.index == cart_items_count -%},{%- endunless -%}
{%- endfor -%}
};
This will create a JSON object that you can use in your JS logic on adjusting cart items quantity. The object would look like that:
{
variant_id_1: max_available_quantity,
variant_id_2: max_available_quantity,
...,
variant_id_x: max_available_quantity
}
If you need to get updated object on adding/removing cart items using AJAX - create a new page template e.g. page.max-qtys.liquid to output this JSON object. Then on adding/removing items, you can get the updated object by requesting any page on your website and adding a ?view=max-qtys query param e.g. /pages/about?view=max-qtys. Don't forget to add {% layout none %} at the beginning of the template file to prevent load your site layout file and just output the object JSON. Below is the code for the page template.
{%- layout none -%}
{%- assign cart_items_count = cart.items | size -%}
{
{%- for item in cart.items -%}
"{{ item.id }}": {{- item.variant.inventory_quantity -}}
{%- unless forloop.index == cart_items_count -%},{%- endunless -%}
{%- endfor -%}
}
Option 2
Use /cart/add.json on adding new items to the cart instead of /cart.update.json or /cart/change.json. Shopify will respond with 422 status code and won't allow you to add more items than available if you use /cart/add.json endpoint.

Duplicate names in sitelinks in google search (Shopify website)

So if you Google "pets go here" or "petsgohere", you will see that the site links under my client's website https://www.petsgohere.com/ 2 of the site links have duplicate names:
"Dog Dog Store" (https://petsgohere.com/pages/dog-store)
"CAT Cat Store" (https://petsgohere.com/pages/cat-store)
What puzzles me is that I don't see duplicate names in the admin area either:
When I open up my theme.liquid, track down how the <title> element, here is how it's rendered:
{% capture seo_title %}
{{ page_title }}
{% if current_tags %}
{%- assign meta_tags = current_tags | join: ', ' %} – {{ 'general.meta.tags' | t: tags: meta_tags -}}
{% endif %}
{% if current_page != 1 %}
– {{ 'general.meta.page' | t: page: current_page }}
{% endif %}
{% unless page_title contains shop.name %}
– {{ shop.name }}
{% endunless %}
{% endcapture %}
<title>{{ seo_title }}</title>
Would anyone out there have any insight on how to resolve this issue or at least know what the issue is?
Can anyone break the code down piece by piece?
In your theme, you are rendering the element with Liquid. That is where you will find some code duplicating your title words. Ensure you render just the right data and not some crazy marketing scheme that is clearly not working!
First thing in your seo_title captured is the page_title. As per the documentation: https://help.shopify.com/en/themes/liquid/objects/page-title
Then the capture will deal with pages in case of more than 1, and the shop name. You can strip this down to be whatever you want. The Liquid capture element simply collects all things rendered in a giant string. So as per my answer, this pattern was invented long ago, to try and make some auto-sense of things in Shopify, and it is not really SEO special, it is simply a mechanical dump. You can do better depending on how you choose to appear. Remembering that page_title is for HUMANS to read, this pattern is weak at best.

Display a set of collections that include a product with a specific tag

I'm trying to set up a page which displays a list of collections, like the general 'list-collections.liquid', but only display collections that contain products with a certain product tag.
I've tried doing it like this:
{% assign var = 'test' %}
{% assign tagtrue = false %}
{% for collection in collections %}
{% unless collection.handle == 'frontpage' %}
{% for product in collection.products %}
{% for tag in product.tags %}
{% if tag contains var %}
{% assign tagtrue = true %}
{% endif %}
{% endfor %}
{% endfor %}
{% if tagtrue == true %}
<a href="{{ collection.url }}" title="{{ 'collections.general.link_title' | t: title: title }}">
{% if collection.image != blank %}
{{ collection | img_url: '480x480' | img_tag: collection.title }}
{% elsif collection.products.first != blank %}
{{ collection.products.first | img_url: '480x480' | img_tag: collection.title }}
{% else %}
{% capture current %}{% cycle 1, 2, 3, 4, 5, 6 %}{% endcapture %}
{{ 'collection-' | append: current | placeholder_svg_tag: 'placeholder-svg placeholder-svg--small' }}
{% endif %}
</a>
<p>
{{ collection.title }}
</p>
{% endif %}
{% endunless %}
{% endfor %}
But when I go to the collection list page this still returns all collections. Any ideas how to do this?
If you look at the documentation, you'll find that a product has a special method on it labelled collections. In other words, that gives you a list of all the collections the product belongs to.
So now on to your question. You ask how you can display a list of collections, but only the ones that contain products with a specific tag. OK... fair enough. You will blow speed out the window, but a simple algorithm might be:
create a collection of products with tag foomanchu
iterate the products in that collection, and use the product.collections
for each collection listed, add it to a list if it has not already been added
Once done that loop, you have the answer. A list of collections for products with a specific tag.
Good luck with performance on that, and remember to keep it simple. That looping is fast for a small shop with limited inventory, but if you have many thousands of skus with a tag spread out across many collections, you'll be challenged for instant rendering.
You can get a speed improvement over David Lazar's answer by using Shopify's map filter.
As with his answer, step 1 is to create a collection with the rule "Product contains tag" and enter the tag that you are using.
Now assuming that you have that collection object in a Liquid variable named collection, you would get the handles of all the collections through a simple map command, followed by a uniq command to strip out all the duplicates:
{% assign all_collection_handles = collection.products | map: 'collections' | map: 'handle | uniq %}
The map filter gets very specific information from the wad of objects, so it's quite a bit faster than iterating through a lot of big objects with a slew of fields you don't care about.
(Note that uniq only works on strings, numbers, or other simple data types, which is why we map all the way to the collections' handles)
Now you can iterate through all_collection_handles to do what you need to do:
{% for handle in all_collection_handles %}
{% assign collection = collections[handle] %}
<!-- Cool stuff here -->
{% endfor %}
Since you should have a much shorter list of collections than you do of products, this should be reasonably performant. Be aware as always that the more heavy-lifting that you're doing in the Liquid code the more likely you'll get page-load delays, so keeping your loops short and using focused filters such as map whenever possible will help keep things running as fast as possible.
Note: If your page starts to suffer from extreme page-load lag, you may want to skip doing this as part of the page-load and just leave a placeholder element, then use Javascript to fetch the information you need and create the display you want.

How to check if we are in cart page Shopify

How can I check if the current page is the cart page in theme.liquid? I tried page.handle=='cart' but it is not working.
You don't need the handle filter, you can just use:
{% if template == 'cart' %}
...
{% endif %}
Neither answer is absolutely correct, including the accepted one.
The cart template as others may have alternates e.g. cart.fancy.liquid which can be accessed via /cart?view=fancy. In that case, the equality operator will not work as expected as template variable will be equal to cart.fancy.
The contains operator is not the best option as well, as it will also be TRUE for product.cartridge.liquid and similar templates.
Based on the above here's the better solution to use in your themes:
{%- assign templateBase = template | slice: 0, 4 -%}
{%- if templateBase == 'cart' -%}
...
{%- endif -%}
It will be TRUE for cart template and all its alternate views.
It will be FALSE for any non-cart templates that may contain
cart sequence in their suffixes i.e. alternate views.
This is another option:
{% if request.path == routes.cart_url %}
We are on the cart page.
{% else %}
We are on some other page.
{% endif %}
I found a solution for this.
using {{template|handle}}
so my code is
{% capture template_handle %}{{ template | handle }}{% endcapture %}
{% if template_handle == 'cart' %}
{% endif %}
Also we can check using:
{% if template contains 'cart' %}
...
{% endif %}