{% comment %} Renders list of products in grid layout Accepts: - product: {Object} product (required) - animation_delay: {Int} animation timing for load - last_element: {Boolean} True when custom image is taking up the first slot for the collection and the loop is on the last element for the page. - index: element index in the loop - block_index: index of the block in Tab collections section - sizes: Image sizes Usage: {% render 'product-grid-item', product: product, index: index, sizes: image_sizes %} {% endcomment %} {%- liquid assign animation_delay = animation_delay | default: 0 assign aos_delay_default = animation_delay | times: 100 assign aos_delay = aos_delay | default: aos_delay_default assign aos_duration = 800 assign layout_desktop = section.settings.layout_desktop assign layout_mobile = section.settings.layout_mobile assign min_defer_index = 8 assign defer = false assign index = index | default: 1 if index > min_defer_index if layout_desktop == 'slider' or layout_mobile == 'slider' assign defer = true endif endif assign columns_desktop = section.settings.grid | plus: 0 assign columns_medium = 2 assign columns_small = 2 assign columns_mobile = section.settings.grid_mobile | plus: 0 if columns_desktop == 0 assign columns_desktop = 4 endif if columns_mobile == 0 assign columns_mobile = 1 endif if columns_desktop == 2 or columns_desktop == 4 assign columns_medium = 2 endif if settings.product_grid_center assign alignment_class = 'product-item--centered' else assign alignment_class = 'product-item--left' endif assign overlay_text_class = 'product-item--outer-text' if settings.overlay_text assign overlay_text_class = 'product-item--overlay-text' endif assign quickview_class = '' if settings.quickview_enable and product.first_available_variant assign quickview_class = 'product-item--has-quickbuy' endif assign has_siblings = false if settings.show_siblings and product.metafields.theme.siblings.value != blank and product.metafields.theme.siblings.type == 'single_line_text_field' assign has_siblings = true endif if settings.show_siblings and product.metafields.theme.sibling_products != blank and product.metafields.theme.sibling_products.type == 'list.product_reference' assign has_siblings = true endif if sizes == blank if section.settings.width == 'wrapper' if settings.grid_style == 'compact' assign sizes = '(min-width: 1400px) calc(80vw / ' | append: columns_desktop | append: '), (min-width: 750px) calc(100vw / ' | append: columns_medium | append: '), (min-width: 480px) calc(100vw / ' | append: columns_small | append: '), calc(100vw / ' | append: columns_mobile | append: ')' else assign sizes = '(min-width: 1400px) calc((80vw - 64px) / ' | append: columns_desktop | append: ' - 32px), (min-width: 750px) calc(100vw / ' | append: columns_medium | append: ' - 22px), (min-width: 480px) calc(100vw / ' | append: columns_small | append: ' - 16px), calc(100vw / ' | append: columns_mobile | append: ')' endif else if settings.grid_style == 'compact' assign sizes = '(min-width: 1400px) calc(100vw / ' | append: columns_desktop | append: '), (min-width: 750px) calc(100vw / ' | append: columns_medium | append: '), (min-width: 480px) calc(100vw / ' | append: columns_small | append: '), calc(100vw / ' | append: columns_mobile | append: ')' else assign sizes = '(min-width: 1400px) calc(100vw / ' | append: columns_desktop | append: ' - 32px), (min-width: 750px) calc(100vw / ' | append: columns_medium | append: ' - 22px), (min-width: 480px) calc(100vw / ' | append: columns_small | append: ' - 16px), calc(100vw / ' | append: columns_mobile | append: ')' endif endif endif assign widths = '136, 160, 180, 220, 254, 284, 292, 320, 480, 528, 640, 720, 960, 1080, 1296, 1512, 1728, 1950' assign aspect_ratio = 1 | divided_by: settings.product_grid_aspect_ratio assign loading = 'eager' if columns_desktop <= 3 assign eager_images_limit = columns_desktop else assign eager_images_limit = columns_desktop | times: 2 endif if layout_desktop == 'slider' and index > 3 assign loading = 'lazy' elsif index > eager_images_limit assign loading = 'lazy' endif if block_index > 1 assign loading = 'lazy' endif -%} {%- if settings.color_swatches -%} {%- assign has_colors = false -%} {%- capture swatches -%} {%- capture swatch_translation -%}{{ 'general.swatches.color' | t }}{%- endcapture -%} {%- assign swatch_labels = swatch_translation | append: ',' | split: ',' -%} {%- for label in swatch_labels -%} {%- assign sanitized_label = label | lstrip | rstrip -%} {%- if product.options_by_name[sanitized_label].values.size > 0 -%} {%- assign has_colors = true -%} {%- capture swatch_values -%} {%- for value in product.options_by_name[sanitized_label].values -%} {{- value -}}: {{- value | handle -}} {%- unless forloop.last -%}, {%- endunless -%} {%- endfor -%} {%- endcapture -%}
{%- break -%} {%- endif -%} {%- endfor -%} {%- endcapture -%} {%- endif -%} {%- liquid assign double_img = false if product.media[1].preview_image and settings.image_hover_enable assign double_img = true endif assign current_variant = product.first_available_variant assign product_url = product.url capture item_unique echo 'product-item--' | append: section.id | append: '-' | append: product.id endcapture assign aos_anchor_default = item_unique | prepend: '#' assign aos_anchor = aos_anchor | default: aos_anchor_default -%} {%- if has_siblings -%} {%- liquid assign sibling_products = product.metafields.theme.sibling_products.value | default: collections[product.metafields.theme.siblings.value].products assign count = product.metafields.theme.sibling_products.value.count | default: collections[product.metafields.theme.siblings.value].products.size assign count_string_one = 'collections.general.colors_with_count.one' | t assign count_string_other = 'collections.general.colors_with_count.other' | t -%} {%- if sibling_products != blank -%} {%- capture siblings_html -%}
{%- for sib_product in sibling_products limit: 50 -%} {%- liquid assign current_class = '' if sib_product.handle == product.handle assign current_class = ' sibling__link--current' endif assign sib_product_price_raw = sib_product.price assign sib_product_compare_at_price_raw = sib_product.compare_at_price assign sib_product_price_raw = sib_product.metafields.app--168074346497.min_auto_discounted_price.value | default: sib_product.price if sib_product.metafields.app--168074346497.discount_percentage.value > 0.01 assign deducted_percentage = 1.0 | minus: sib_product.metafields.app--168074346497.discount_percentage.value assign sib_product_price_raw = sib_product.price | divided_by: 100.0 | times: deducted_percentage | times: 100.0 | ceil endif if sib_product_price_raw < sib_product.price assign sib_product_compare_at_price_raw = sib_product.price if sib_product.compare_at_price > sib_product_compare_at_price_raw assign sib_product_compare_at_price_raw = sib_product.compare_at_price endif endif if settings.currency_code_enable assign sib_product_price = sib_product_price_raw | money_with_currency else assign sib_product_price = sib_product_price_raw | money endif if sib_product_compare_at_price_raw > sib_product_price_raw if settings.currency_code_enable assign sib_product_compare_at_price = sib_product_compare_at_price_raw | money_with_currency else assign sib_product_compare_at_price = sib_product_compare_at_price_raw | money endif endif if sib_product.price == 0 and sib_product.price_varies == false assign sib_product_price = 'general.money.free' | t endif assign sib_cutline = sib_product.metafields.theme.cutline | strip_html | default: sib_product.title | strip_html assign sib_color = sib_product.metafields.theme.sibling_color.value | default: sib_product.metafields.theme.sibling_colour.value | default: sib_product.metafields.theme.siblings_color.value | default: sib_product.metafields.theme.siblings_colour.value | default: sib_product.metafields.theme.siblings_colors.value | default: sib_product.metafields.theme.siblings_colours.value assign swatch_color = sib_color | handle -%}
{%- if settings.sibling_style == 'image' -%} {%- liquid case settings.swatch_size when 'regular' assign sibling_width = 1.15 | times: settings.type_body_size | divided_by: 100.0 | times: 16 | round when 'large' assign sibling_width = 2.3 | times: settings.type_body_size | divided_by: 100.0 | times: 16 | round endcase assign sibling_sizes = sibling_width | append: 'px' assign sibling_width_15x = sibling_width | times: 1.5 assign sibling_width_2x = sibling_width | times: 2 assign sibling_widths = sibling_width | append: ', ' | append: sibling_width_15x | append: ', ' | append: sibling_width_2x -%} {%- endif -%}
{%- endfor -%}
{{ count }} {{ count | pluralize: count_string_one, count_string_other }}
{%- endcapture -%} {%- endif -%} {%- endif -%} {%- capture over_image_content -%} {%- liquid assign product_tags = product.tags | join: ',' | append: ',' assign preorder = false assign is_preorder_meta = false assign on_sale = false assign sold_out = false assign badge = '' if product.metafields.theme.badge != blank and product.metafields.theme.badge.type == 'single_line_text_field' assign badge = product.metafields.theme.badge.value endif if badge == '' and product_tags contains '_badge_' assign badge = product_tags | split: '_badge_' assign badge = badge[1] | split: ',' | first | replace: '_', ' ' endif if product.metafields.theme.preorder.type == 'boolean' and product.metafields.theme.preorder.value == true assign is_preorder_meta = true endif if product_tags contains '_preorder' or is_preorder_meta assign preorder = true endif if product.compare_at_price > product.price and settings.sale_tags_enable assign on_sale = true endif unless product.available assign sold_out = true endunless -%} {%- if badge != '' -%} {{ badge }} {%- elsif preorder and sold_out == false -%} {{ 'products.product.pre_order' | t }} {%- elsif on_sale and sold_out == false -%} {{ 'products.product.on_sale' | t }} {%- endif -%} {%- if settings.quickview_enable and current_variant -%} {%- liquid assign is_preorder_meta_exist = false assign is_preorder_tag_exist = false assign sibling_property_name = 'general.siblings.label' | t | strip_html | escape assign sibling_property_value = '' if siblings_html != blank and product.variants.size == 1 assign title_down = product.title | downcase assign sibling = product.metafields.theme.sibling_color.value | default: product.metafields.theme.sibling_colour.value | default: product.metafields.theme.siblings_color.value | default: product.metafields.theme.siblings_colour.value | default: product.metafields.theme.siblings_colors.value | default: product.metafields.theme.siblings_colours.value assign sibling_down = sibling | downcase unless title_down contains sibling_down assign sibling_property_value = sibling | strip_html | escape endunless endif if current_variant.available and product.metafields.theme.preorder.type == 'boolean' and product.metafields.theme.preorder.value == true assign is_preorder_meta_exist = true endif if current_variant.available and product.tags contains '_preorder' assign is_preorder_tag_exist = true endif if is_preorder_meta_exist or is_preorder_tag_exist assign preorder_name = 'products.product.sale_type' | t | strip_html | escape assign preorder_value = 'products.product.pre_order' | t | strip_html | escape endif assign unique = section.id | append: '-' | append: product.id -%}
{%- if product.variants.size == 1 -%} {%- assign product_form_id = 'ProductForm--' | append: unique -%} {%- form 'product', product, id: product_form_id -%} {%- if sibling_property_value != blank -%} {%- endif -%} {%- if preorder_value != blank -%} {%- endif -%} {%- endform -%} {%- else -%} {%- endif -%} {%- unless product.has_only_default_variant -%} {%- render 'product-quick-add-modal-template', product_id: product.id, unique: unique -%} {%- endunless -%}
{%- endif -%} {%- endcapture -%} {%- liquid capture product_item_cutline if settings.show_cutline and product.metafields.theme.cutline != blank and product.metafields.theme.cutline.type == 'single_line_text_field' assign product_title_downcase = product.title | strip_html | escape | downcase assign cutline_downcase = product.metafields.theme.cutline.value | downcase unless product_title_downcase contains cutline_downcase echo product.metafields.theme.cutline.value endunless endif endcapture -%} {%- capture image_animations -%} data-aos="img-in" data-aos-delay="{{ aos_delay }}" data-aos-duration="{{ aos_duration }}" data-aos-anchor="{{ aos_anchor }}" data-aos-easing="ease-out-quart" {%- endcapture -%}
{%- if product.media.size > 0 -%}
{%- liquid assign fetchpriority = 'auto' assign preload = false if index <= eager_images_limit assign fetchpriority = 'high' assign preload = true endif capture featured_image render 'image' image: product.featured_media.preview_image, aspect_ratio: aspect_ratio, sizes: sizes, widths: widths, loading: loading, fetchpriority: fetchpriority, preload: preload, attributes: image_animations, cover: true endcapture -%} {%- if defer -%} {%- else -%} {{ featured_image }} {%- endif -%} {%- if settings.color_swatches and current_variant -%} {%- assign image_inner_empty = true -%} {%- for variant in product.variants -%} {%- if variant.featured_image != blank -%} {%- assign image_inner_empty = false -%} {%- assign variant_title = variant.title | replace: '"', "'" -%} {%- endif -%} {%- endfor -%} {%- if image_inner_empty -%}   {%- endif -%} {%- else -%}   {%- endif -%}
{%- if double_img -%} {%- assign media = product.media[1] -%} {%- if media.media_type == 'video' or media.media_type == 'external_video' -%} {%- else -%} {%- endif -%} {%- endif -%} {%- else -%} {%- comment -%} Show Empty image if product has no media {%- endcomment -%}
{%- endif -%} {%- if has_siblings -%}
{%- endif -%}
{{ over_image_content }}
{%- if settings.product_grid_show_rating and product.metafields.reviews.rating.value != blank -%}
{% render 'product-rating', product: product %}
{%- endif -%}

{{ product.title | strip_html | escape }}

{%- if has_siblings or product_item_cutline != blank -%} {%- assign cutline_color = settings.cutline_color -%} {%- unless cutline_color == 'rgba(0,0,0,0)' or cutline_color == blank -%} {%- assign style = '--text-light:' | append: cutline_color -%} {%- endunless -%} {{ product_item_cutline }} {%- endif -%} {%- if has_siblings -%} {%- endif -%}
{% comment %} Price on product grid item {% endcomment %} {%- liquid assign product_price_raw = product.metafields.app--168074346497.min_auto_discounted_price.value | default: product.price assign product_price_min_raw = product.price_min assign product_compare_at_price_raw = product.compare_at_price if product.metafields.app--168074346497.discount_percentage.value > 0.01 assign deducted_percentage = 1.0 | minus: product.metafields.app--168074346497.discount_percentage.value assign product_price_raw = product.price | divided_by: 100.0 | times: deducted_percentage | times: 100.0 | ceil assign product_price_min_raw = product_price_raw assign product_compare_at_price_raw = product.price if product.compare_at_price > product_compare_at_price_raw assign product_compare_at_price_raw = product.compare_at_price endif elsif product_price_raw < product.price assign product_price_min_raw = product_price_raw assign product_compare_at_price_raw = product.price if product.compare_at_price > product_compare_at_price_raw assign product_compare_at_price_raw = product.compare_at_price endif endif if settings.currency_code_enable assign product_price_min = product_price_min_raw | money_with_currency assign product_compare_at_price = product_compare_at_price_raw | money_with_currency else assign product_price_min = product_price_min_raw | money assign product_compare_at_price = product_compare_at_price_raw | money endif -%} {% if product.available %} {% if product.price_varies %} {{ 'products.general.from' | t }} {% endif %} {%- if product_price == 0 and product.price_varies == false -%} {{ 'general.money.free' | t }} {%- else -%} {{ product_price_min }} {%- endif -%} {% if product_compare_at_price_raw > product_price_raw %} {{ product_compare_at_price }} {% endif %} {% else %} {{ 'products.product.sold_out' | t }} {% endif %} {% if current_variant.unit_price %} {% capture unit_price_separator %} {{ 'general.accessibility.unit_price_separator' | t }}  {% endcapture %} {% capture unit_price_base_unit %} {% if current_variant.unit_price_measurement.reference_value != 1 %} {{ current_variant.unit_price_measurement.reference_value }} {% endif %} {{ current_variant.unit_price_measurement.reference_unit }} {% endcapture %}
{{ 'products.product.unit_price_label' | t }} {% if settings.currency_code_enable %}{{ current_variant.unit_price | money_with_currency }}{% else %}{{ current_variant.unit_price | money }}{% endif %}{{ unit_price_separator }}{{ unit_price_base_unit }} {% endif %}
{%- if siblings_html != blank -%} {{ siblings_html }} {%- elsif has_colors -%}
{{ swatches }} {%- if has_colors -%}   {%- endif -%}
{%- endif -%}