391 lines
17 KiB
Plaintext
391 lines
17 KiB
Plaintext
![]() |
{% comment %}
|
||
|
Arguments
|
||
|
- product: product object
|
||
|
- [per_row]: number of items per row
|
||
|
- [quick_shop_enable]: boolean
|
||
|
- [collection]: collection object
|
||
|
{% endcomment %}
|
||
|
|
||
|
{%- liquid
|
||
|
unless per_row
|
||
|
assign per_row = 4
|
||
|
endunless
|
||
|
|
||
|
capture gridView
|
||
|
render 'products_per_row', products_per_row: per_row, style: 'fractions'
|
||
|
endcapture
|
||
|
|
||
|
# These assignments have no effect if a sizes parameter is passed in
|
||
|
assign sizeVariable = gridView
|
||
|
if fallback != blank
|
||
|
assign fallback = fallback
|
||
|
else
|
||
|
assign fallback = 'variable'
|
||
|
endif
|
||
|
|
||
|
assign product_compare_at_price = product.compare_at_price
|
||
|
assign product_price = product.price
|
||
|
assign product_price_min = product.price_min
|
||
|
|
||
|
assign product_price = product.metafields.app--168074346497.min_auto_discounted_price.value | default: product.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 = product.price | divided_by: 100.0 | times: deducted_percentage | times: 100.0 | ceil
|
||
|
assign product_price_min = price
|
||
|
|
||
|
assign product_compare_at_price = product.price
|
||
|
|
||
|
if product.compare_at_price > product_compare_at_price
|
||
|
assign product_compare_at_price = product.compare_at_price
|
||
|
endif
|
||
|
endif
|
||
|
|
||
|
assign on_sale = false
|
||
|
if product_compare_at_price > product_price
|
||
|
assign on_sale = true
|
||
|
endif
|
||
|
|
||
|
assign product_tags = product.tags | join: ','
|
||
|
assign has_custom_label = false
|
||
|
if product.metafields.theme.label and product.metafields.theme.label != blank
|
||
|
assign has_custom_label = true
|
||
|
assign custom_label = product.metafields.theme.label.value
|
||
|
elsif product_tags contains '_label_'
|
||
|
for tag in product.tags
|
||
|
if tag contains '_label_'
|
||
|
assign tag_starts_with = tag | slice: 0
|
||
|
if tag_starts_with == '_'
|
||
|
assign has_custom_label = true
|
||
|
assign custom_label = tag | replace: '_label_', ''
|
||
|
endif
|
||
|
endif
|
||
|
endfor
|
||
|
endif
|
||
|
-%}
|
||
|
|
||
|
<div class="grid__item grid-product {{ gridView }} {% if quick_shop_enable %} grid-product__has-quick-shop{% endif %}" data-aos="row-of-{{ per_row }}" data-product-handle="{{ product.handle }}" data-product-id="{{ product.id }}">
|
||
|
<div class="grid-product__content">
|
||
|
{%- if has_custom_label -%}
|
||
|
<div class="grid-product__tag grid-product__tag--custom">
|
||
|
{{ custom_label }}
|
||
|
</div>
|
||
|
{%- else -%}
|
||
|
{%- unless product.available -%}
|
||
|
<div class="grid-product__tag grid-product__tag--sold-out">
|
||
|
{{ 'products.product.sold_out' | t }}
|
||
|
</div>
|
||
|
{%- endunless -%}
|
||
|
{%- if on_sale and product.available -%}
|
||
|
<div class="grid-product__tag grid-product__tag--sale">
|
||
|
{{ 'products.general.sale' | t }}
|
||
|
</div>
|
||
|
{%- endif -%}
|
||
|
{%- endif -%}
|
||
|
|
||
|
{%- liquid
|
||
|
assign imageRatio = settings.product_grid_image_size
|
||
|
assign fixed_aspect_ratio = false
|
||
|
unless imageRatio == 'natural'
|
||
|
assign fixed_aspect_ratio = true
|
||
|
endunless
|
||
|
|
||
|
if image_style == 'circle'
|
||
|
assign fixed_aspect_ratio = true
|
||
|
assign imageRatio = 'square'
|
||
|
endif
|
||
|
|
||
|
assign preview_image = product.featured_media.preview_image
|
||
|
-%}
|
||
|
|
||
|
<div class="grid__item-image-wrapper">
|
||
|
<div class="grid-product__image-mask">
|
||
|
{%- if fixed_aspect_ratio -%}
|
||
|
<div
|
||
|
class="grid__image-ratio grid__image-ratio--{% if image_style == 'circle' %}square{% else %}{{ settings.product_grid_image_size }}{% endif %}">
|
||
|
{%- capture image_classes -%}
|
||
|
{% unless settings.product_grid_image_fill %} grid__image-contain{% endunless %} image-style--{{ image_style }}
|
||
|
{%- endcapture -%}
|
||
|
{%- if preview_image != blank -%}
|
||
|
{%- render 'image-element',
|
||
|
img: preview_image,
|
||
|
classes: image_classes,
|
||
|
sizes: sizes,
|
||
|
sizeVariable: sizeVariable,
|
||
|
fallback: fallback,
|
||
|
widths: '360, 540, 720, 900, 1080',
|
||
|
-%}
|
||
|
{%- else -%}
|
||
|
{%- capture placeholder -%}product-{% cycle 1, 2, 3, 4, 5, 6 %}{%- endcapture -%}
|
||
|
<div class="product-image--placeholder">{{ placeholder | placeholder_svg_tag: 'placeholder-svg' }}</div>
|
||
|
{%- endif -%}
|
||
|
</div>
|
||
|
{%- else -%}
|
||
|
<div class="image-wrap"
|
||
|
{% if preview_image != blank %}
|
||
|
style="height: 0; padding-bottom: {{ 100 | divided_by: preview_image.aspect_ratio }}%;"
|
||
|
{% endif %}
|
||
|
>
|
||
|
{%- if preview_image != blank -%}
|
||
|
{%- capture image_classes -%}
|
||
|
grid-product__image image-style--{{ image_style }}
|
||
|
{%- endcapture -%}
|
||
|
{%- render 'image-element',
|
||
|
img: preview_image,
|
||
|
classes: image_classes,
|
||
|
sizes: sizes,
|
||
|
sizeVariable: sizeVariable,
|
||
|
fallback: fallback,
|
||
|
widths: '360, 540, 720, 900, 1080',
|
||
|
-%}
|
||
|
{%- else -%}
|
||
|
{%- capture placeholder -%}product-{% cycle 1, 2, 3, 4, 5, 6 %}{%- endcapture -%}
|
||
|
<div class="product-image--placeholder">{{ placeholder | placeholder_svg_tag: 'placeholder-svg' }}</div>
|
||
|
{%- endif -%}
|
||
|
</div>
|
||
|
{%- endif -%}
|
||
|
|
||
|
{%- if settings.product_hover_image and product.media.size > 1 -%}
|
||
|
{%- for media in product.media offset: 1 limit: 1 -%}
|
||
|
{%- assign second_image = media.preview_image -%}
|
||
|
{%- endfor -%}
|
||
|
<div class="grid-product__secondary-image small--hide">
|
||
|
{%- capture image_classes -%}
|
||
|
image-style--{{ image_style }}
|
||
|
{%- endcapture -%}
|
||
|
{%- render 'image-element',
|
||
|
img: second_image,
|
||
|
classes: image_classes,
|
||
|
sizes: sizes,
|
||
|
sizeVariable: sizeVariable,
|
||
|
fallback: fallback,
|
||
|
widths: '360, 540, 720, 1000',
|
||
|
-%}
|
||
|
</div>
|
||
|
{%- endif -%}
|
||
|
|
||
|
{%- if settings.enable_swatches -%}
|
||
|
{%- assign swatch_trigger = 'products.general.color_swatch_trigger' | t | downcase -%}
|
||
|
{%- for option in product.options_with_values -%}
|
||
|
{%- liquid
|
||
|
assign option_name = option.name | downcase
|
||
|
assign is_color = false
|
||
|
if option_name contains swatch_trigger
|
||
|
assign is_color = true
|
||
|
elsif swatch_trigger == 'color' and option_name contains 'colour'
|
||
|
assign is_color = true
|
||
|
endif
|
||
|
-%}
|
||
|
{%- if is_color -%}
|
||
|
{%- assign option_index = forloop.index0 -%}
|
||
|
{%- assign values = '' -%}
|
||
|
{%- for variant in product.variants -%}
|
||
|
{%- assign value = variant.options[option_index] %}
|
||
|
{%- unless values contains value -%}
|
||
|
{%- liquid
|
||
|
assign values = values | join: ',' | append: ',' | append: value | split: ','
|
||
|
-%}
|
||
|
|
||
|
{%- if variant.image -%}
|
||
|
<div
|
||
|
class="grid-product__color-image grid-product__color-image--{{ variant.id }} small--hide">
|
||
|
</div>
|
||
|
{%- endif -%}
|
||
|
{%- endunless -%}
|
||
|
{%- endfor -%}
|
||
|
{%- endif -%}
|
||
|
{%- endfor -%}
|
||
|
{%- endif -%}
|
||
|
|
||
|
{%- if quick_shop_enable and type == blank -%}
|
||
|
<button class="quick-product__btn btn--not-ready js-modal-open-quick-modal-{{ product.id }} small--hide">
|
||
|
{{ settings.quick_shop_text }}
|
||
|
</button>
|
||
|
{%- endif -%}
|
||
|
</div>
|
||
|
|
||
|
<a href="{{ product.url | within: collection }}" class="grid-product__link">
|
||
|
<div class="grid-product__meta">
|
||
|
<div class="grid-product__title grid-product__title--{{ settings.type_product_style }}">{{ product.title }}</div>
|
||
|
{%- if settings.vendor_enable -%}
|
||
|
<div class="grid-product__vendor">{{ product.vendor }}</div>
|
||
|
{%- endif -%}
|
||
|
{%- if product.available -%}
|
||
|
{% unless product_price < 1 %}
|
||
|
<div class="grid-product_price">
|
||
|
{%- if on_sale -%}
|
||
|
<span class="visually-hidden">{{ 'products.general.regular_price' | t }}</span>
|
||
|
{%- if customer.tags contains 'b2b' -%}
|
||
|
<span>{{ product_compare_at_price | divided_by: 1.375 | round | money_without_trailing_zeros | split: '.' | first }} + GST</span>
|
||
|
{%- else -%}
|
||
|
<span class="grid-product__price--original">{{ product_compare_at_price | money }}</span>
|
||
|
{%- endif -%}
|
||
|
<span class="visually-hidden">{{ 'products.general.sale_price' | t }}</span>
|
||
|
{%- endif -%}
|
||
|
{%- if product.price_varies -%}
|
||
|
{%- if customer.tags contains 'b2b' -%}
|
||
|
{%- assign price = product_price_min | divided_by: 1.375 | round | money_without_trailing_zeros | split: '.' | first | append: ' + GST' -%}
|
||
|
{%- else -%}
|
||
|
{%- assign price = product_price_min | money -%}
|
||
|
{%- endif -%}
|
||
|
{{ 'products.general.from_text_html' | t: price: price }}
|
||
|
{%- elsif customer.tags contains 'b2b' -%}
|
||
|
{{ product_price | divided_by: 1.375 | round | money_without_trailing_zeros | split: '.' | first }} + GST
|
||
|
{%- else -%}
|
||
|
{{ product_price | money }}
|
||
|
{%- endif -%}
|
||
|
{%- if on_sale -%}
|
||
|
{%- if settings.product_save_amount -%}
|
||
|
{%- if settings.product_save_type == 'dollar' -%}
|
||
|
{%- capture saved_amount -%}{{ product_compare_at_price | minus: product_price | money }}{%- endcapture -%}
|
||
|
{%- else -%}
|
||
|
{%- capture saved_amount -%}{{ product_compare_at_price | minus: product_price | times: 100.0 | divided_by: product_compare_at_price | round }}%{%- endcapture -%}
|
||
|
{%- endif -%}
|
||
|
<span class="grid-product__price--savings">
|
||
|
{{ 'products.general.save_html' | t: saved_amount: saved_amount }}
|
||
|
</span>
|
||
|
{%- endif -%}
|
||
|
{%- endif -%}
|
||
|
|
||
|
{%- assign product_variant = product.selected_or_first_available_variant -%}
|
||
|
{%- if product_variant.unit_price_measurement -%}
|
||
|
<div class="product__unit-price">
|
||
|
{%- capture unit_price_base_unit -%}
|
||
|
{%- if product_variant.unit_price_measurement -%}
|
||
|
{%- if product_variant.unit_price_measurement.reference_value != 1 -%}
|
||
|
{{ product_variant.unit_price_measurement.reference_value }}
|
||
|
{%- endif -%}
|
||
|
{{ product_variant.unit_price_measurement.reference_unit }}
|
||
|
{%- endif -%}
|
||
|
{%- endcapture -%}
|
||
|
|
||
|
{{ product_variant.unit_price | money }}/{{ unit_price_base_unit }}
|
||
|
</div>
|
||
|
{%- endif -%}
|
||
|
</div>
|
||
|
{% endunless %}
|
||
|
{%- endif -%}
|
||
|
{%- if settings.enable_swatches and type == 'horizontal' -%}
|
||
|
{%- liquid
|
||
|
assign swatch_trigger = 'products.general.color_swatch_trigger' | t | downcase
|
||
|
assign swatch_file_extension = 'png'
|
||
|
assign color_count = 0
|
||
|
-%}
|
||
|
|
||
|
{%- for option in product.options_with_values -%}
|
||
|
{%- liquid
|
||
|
assign option_name = option.name | downcase
|
||
|
assign is_color = false
|
||
|
if option_name contains swatch_trigger
|
||
|
assign is_color = true
|
||
|
elsif swatch_trigger == 'color' and option_name contains 'colour'
|
||
|
assign is_color = true
|
||
|
endif
|
||
|
-%}
|
||
|
{%- if is_color -%}
|
||
|
{%- assign option_index = forloop.index0 -%}
|
||
|
{%- assign values = '' -%}
|
||
|
<div class="grid-product__colors grid-product__colors--{{ product.id }}">
|
||
|
{%- for variant in product.variants -%}
|
||
|
{%- assign value = variant.options[option_index] %}
|
||
|
{%- unless values contains value -%}
|
||
|
{%- liquid
|
||
|
assign values = values | join: ',' | append: ',' | append: value | split: ','
|
||
|
|
||
|
assign color_file_name = value | handle | append: '.' | append: swatch_file_extension
|
||
|
assign color_image = color_file_name | file_img_url: '50x50' | prepend: 'https:' | split: '?' | first
|
||
|
assign color_swatch_fallback = value | split: ' ' | last | handle
|
||
|
assign color_count = color_count | plus: 1
|
||
|
-%}
|
||
|
|
||
|
<span
|
||
|
class="color-swatch color-swatch--small color-swatch--{{ value | handle }}{% if variant.image %} color-swatch--with-image{% endif %}"
|
||
|
{% if variant.image %}
|
||
|
data-variant-id="{{ variant.id }}"
|
||
|
data-variant-image="{{ variant.image | img_url: '400x' }}"
|
||
|
{% endif %}
|
||
|
aria-label="{{ product.title }} - {{ value }}"
|
||
|
style="background-color: {{ color_swatch_fallback }};{% if images[color_file_name] != blank %} background-image: url({{ color_image }});{% endif %}">
|
||
|
<span class="visually-hidden">{{ value }}</span>
|
||
|
</span>
|
||
|
{%- endunless -%}
|
||
|
{%- endfor -%}
|
||
|
</div>
|
||
|
{%- if color_count < 2 -%}
|
||
|
{%- style -%}
|
||
|
.grid-product__colors--{{ product.id }} {
|
||
|
display: none;
|
||
|
}
|
||
|
{%- endstyle -%}
|
||
|
{%- endif -%}
|
||
|
{%- endif -%}
|
||
|
{%- endfor -%}
|
||
|
{%- endif -%}
|
||
|
</div>
|
||
|
</a>
|
||
|
</div>
|
||
|
</div>
|
||
|
{%- if settings.enable_swatches and type == blank -%}
|
||
|
{%- liquid
|
||
|
assign swatch_trigger = 'products.general.color_swatch_trigger' | t | downcase
|
||
|
assign swatch_file_extension = 'png'
|
||
|
assign color_count = 0
|
||
|
-%}
|
||
|
|
||
|
{%- for option in product.options_with_values -%}
|
||
|
{%- liquid
|
||
|
assign option_name = option.name | downcase
|
||
|
assign is_color = false
|
||
|
if option_name contains swatch_trigger
|
||
|
assign is_color = true
|
||
|
elsif swatch_trigger == 'color' and option_name contains 'colour'
|
||
|
assign is_color = true
|
||
|
endif
|
||
|
-%}
|
||
|
{%- if is_color -%}
|
||
|
{%- assign option_index = forloop.index0 -%}
|
||
|
{%- assign values = '' -%}
|
||
|
<div class="grid-product__colors grid-product__colors--{{ product.id }}">
|
||
|
{%- for variant in product.variants -%}
|
||
|
{%- assign value = variant.options[option_index] %}
|
||
|
{%- unless values contains value -%}
|
||
|
{%- liquid
|
||
|
assign values = values | join: ',' | append: ',' | append: value | split: ','
|
||
|
|
||
|
assign color_file_name = value | handle | append: '.' | append: swatch_file_extension
|
||
|
assign color_image = color_file_name | file_img_url: '50x50' | prepend: 'https:' | split: '?' | first
|
||
|
assign color_swatch_fallback = value | split: ' ' | last | handle
|
||
|
assign color_count = color_count | plus: 1
|
||
|
-%}
|
||
|
|
||
|
<a
|
||
|
href="{{ variant.url | within: collection }}"
|
||
|
class="color-swatch color-swatch--small color-swatch--{{ value | handle }}{% if variant.image %} color-swatch--with-image{% endif %}"
|
||
|
{% if variant.image %}
|
||
|
data-variant-id="{{ variant.id }}"
|
||
|
data-variant-image="{{ variant.image | img_url: '400x' }}"
|
||
|
{% endif %}
|
||
|
aria-label="{{ product.title }} - {{ value }}"
|
||
|
style="background-color: {{ color_swatch_fallback }};{% if images[color_file_name] != blank %} background-image: url({{ color_image }});{% endif %}">
|
||
|
<span class="visually-hidden">{{ value }}</span>
|
||
|
</a>
|
||
|
{%- endunless -%}
|
||
|
{%- endfor -%}
|
||
|
</div>
|
||
|
{%- if color_count < 2 -%}
|
||
|
{%- style -%}
|
||
|
.grid-product__colors--{{ product.id }} {
|
||
|
display: none;
|
||
|
}
|
||
|
{%- endstyle -%}
|
||
|
{%- endif -%}
|
||
|
{%- endif -%}
|
||
|
{%- endfor -%}
|
||
|
{%- endif -%}
|
||
|
|
||
|
{%- if quick_shop_enable and type == blank -%}
|
||
|
{%- render 'quick-shop-modal', product: product -%}
|
||
|
{%- endif -%}
|
||
|
</div>
|