commit de8999073cbe273b74885c78585d481185b613b6 Author: Axel Date: Thu Apr 30 01:49:11 2026 +0800 first commit diff --git a/snippets/card-product.liquid b/snippets/card-product.liquid new file mode 100644 index 0000000..7bb9705 --- /dev/null +++ b/snippets/card-product.liquid @@ -0,0 +1,970 @@ +{% comment %} + Renders a product card + + Accepts: + - card_product: {Object} Product Liquid object (optional) + - media_aspect_ratio: {String} Size of the product image card. Values are "square" and "portrait". Default is "square" (optional) + - image_shape: {String} Image mask to apply to the product image card. Values are "arch", "blob", "chevronleft", "chevronright", "diamond", "parallelogram", and "round". (optional) + - show_secondary_image: {String} Show the secondary image on hover. Values are "inherit" and "disabled". Default: inherit (optional) + - show_carousel: {String} Show the product image carousel. Values are "inherit" and "disabled". Default: inherit (optional) + - show_vendor: {Boolean} Show the product vendor. Default: false + - show_rating: {Boolean} Show the product rating. Default: false + - show_price: {Boolean} Show the product price. Default: True + - custom_badge_label: {String} Custom label for the badge + - extend_height: {Boolean} Card height extends to available container space. Default: true (optional) + - skip_styles: {Boolean} Don't include component styles. Useful when rendering multiple product cards in a loop. Default: false (optional) + - quick_add: {Boolean} Show the quick add button. + - section_id: {String} The ID of the section that contains this card. + - horizontal_class: {Boolean} Add a card--horizontal class if set to true. Default: false (optional) + - horizontal_quick_add: {Boolean} Changes the quick add button styles when set to true. Default: false (optional) + - placeholder_image: {String} The placeholder image to use when no product exists. Default: 'product-apparel-2' (optional) + + Usage: + {% render 'card-product', show_vendor: section.settings.show_vendor %} +{% endcomment %} + +{% liquid + if hide_price == blank + assign hide_price = false + endif + + if show_sold_out_badge == blank + assign show_sold_out_badge = false + endif + + if show_sale_badge == blank + assign show_sale_badge = false + endif +%} + +{% comment %} hide for professionals {% endcomment %} +{% assign is_pro_customer = false %} + +{% if customer %} + {% if customer.tags contains 'Pro level 1' + or customer.tags contains 'Pro level 2' + or customer.tags contains 'Pro level 3' %} + {% assign is_pro_customer = true %} + {% endif %} +{% endif %} + +{% assign is_professional_product = false %} +{% for c in card_product.collections %} + {% if c.handle == 'professional-use' %} + {% assign is_professional_product = true %} + {% break %} + {% endif %} +{% endfor %} + +{% if media_aspect_ratio %} + {% if media_aspect_ratio != 'inherit' %} + {% assign image_aspect_ratio = media_aspect_ratio %} + {% if media_aspect_ratio == 'circle' %} + {% assign image_aspect_ratio = '100%' %} + {% endif %} + {% style %} + #shopify-section-{{ section.id }}{ + --dbtfy-image-crop-ratio: {{ image_aspect_ratio }}; + } + {% endstyle %} + {% else %} + {% assign media_aspect_ratio = settings.dbtfy_product_image_crop_ratio %} + {% endif %} +{% endif %} + +{% if image_crop_position and image_crop_position != 'inherit' %} + {% style %} + #shopify-section-{{ section.id }}{ + --dbtfy-image-crop-position: {{ image_crop_position }}; + } + {% endstyle %} +{% endif %} + +{%- unless skip_styles -%} + {{ 'component-rating.css' | asset_url | stylesheet_tag }} + {{ 'component-volume-pricing.css' | asset_url | stylesheet_tag }} + + {{ 'component-price.css' | asset_url | stylesheet_tag }} + {{ 'quick-order-list.css' | asset_url | stylesheet_tag }} + {{ 'quantity-popover.css' | asset_url | stylesheet_tag }} +{%- endunless -%} +{%- if card_product and card_product != empty -%} + {%- liquid + if show_secondary_image == 'inherit' and settings.dbtfy_show_second_image_on_hover + assign show_secondary_image = true + else + assign show_secondary_image = false + endif + + if show_carousel == 'inherit' and settings.dbtfy_show_product_card_carousel + assign show_carousel = true + else + assign show_carousel = false + endif + -%} + +{%- else -%} + +{%- endif -%} diff --git a/snippets/price.liquid b/snippets/price.liquid new file mode 100644 index 0000000..badefca --- /dev/null +++ b/snippets/price.liquid @@ -0,0 +1,246 @@ +{% comment %} + Renders a list of product's price (regular, sale) + + Accepts: + - product: {Object} Product Liquid object (optional) + - placeholder: {Boolean} Renders a placeholder price (optional) + - use_variant: {Boolean} Renders selected or first variant price instead of overall product pricing (optional) + - show_badges: {Boolean} Renders 'Sale' and 'Sold Out' tags if the product matches the condition (optional) + - price_class: {String} Adds a price class to the price element (optional) + - show_compare_at_price: {Boolean} Renders the compare at price if the product matches the condition (optional) + + Usage: + {% render 'price', product: product %} +{% endcomment %} +{%- liquid + if use_variant + assign target = product.selected_or_first_available_variant + elsif placeholder + assign target = null + else + assign target = product + endif + + assign compare_at_price = target.compare_at_price + assign price = target.price | default: 1999 + assign price_min = product.price_min + assign price_max = product.price_max + assign available = target.available | default: false + + comment + start Yagi app code + endcomment + assign public_or_tags_matched = true + + if product.metafields.app--168074346497.segment_tags.value.size > 0 + assign public_or_tags_matched = false + endif + + for etag in product.metafields.app--168074346497.segment_tags.value + if customer.tags contains etag + assign public_or_tags_matched = true + break + endif + endfor + + if public_or_tags_matched + if use_variant + assign price = target.metafields.app--168074346497.auto_discounted_price.value | default: target.price + + if target.metafields.app--168074346497.discount_type.value != nil and target.metafields.app--168074346497.discount_type.value != "fixed" and product.metafields.app--168074346497.discount_percentage.value > 0.01 + assign deducted_percentage = 1.0 | minus: product.metafields.app--168074346497.discount_percentage.value + + if target.metafields.app--168074346497.discount_percentage.value > 0.01 + assign deducted_percentage = 1.0 | minus: target.metafields.app--168074346497.discount_percentage.value + endif + + assign price = target.price | divided_by: 100.0 | times: deducted_percentage | times: 100.0 | ceil + assign price_min = price + assign price_max = product.price_max | divided_by: 100.0 | times: deducted_percentage | times: 100.0 | ceil + + assign compare_at_price = target.price + + if target.compare_at_price > compare_at_price + assign compare_at_price = target.compare_at_price + endif + endif + + if shop.metafields.app--168074346497.discount_percentage.value > 0.005 + assign discount_percentage = shop.metafields.app--168074346497.discount_percentage.value | times: 1.0 + assign deducted_percentage = 1.0 | minus: discount_percentage + + assign price = target.price | divided_by: 100.0 | times: deducted_percentage | times: 100.0 | ceil + assign price_min = price + assign price_max = product.price_max | divided_by: 100.0 | times: deducted_percentage | times: 100.0 | ceil + + assign compare_at_price = target.price + + if target.compare_at_price > compare_at_price + assign compare_at_price = target.compare_at_price + endif + endif + + if price < target.price and compare_at_price == blank + assign compare_at_price = target.price + endif + else + assign 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 price = product.price | divided_by: 100.0 | times: deducted_percentage | times: 100.0 | ceil + assign price_min = price + assign price_max = product.price_max | divided_by: 100.0 | times: deducted_percentage | times: 100.0 | ceil + + assign compare_at_price = product.price + + if product.compare_at_price > compare_at_price + assign compare_at_price = product.compare_at_price + endif + endif + + if shop.metafields.app--168074346497.discount_percentage.value > 0.005 + assign discount_percentage = shop.metafields.app--168074346497.discount_percentage.value | times: 1.0 + assign deducted_percentage = 1.0 | minus: discount_percentage + + assign price = product.price | divided_by: 100.0 | times: deducted_percentage | times: 100.0 | ceil + assign price_min = price + assign price_max = product.price_max | divided_by: 100.0 | times: deducted_percentage | times: 100.0 | ceil + + assign compare_at_price = product.price + + if product.compare_at_price > compare_at_price + assign compare_at_price = product.compare_at_price + endif + endif + + if price < product.price and compare_at_price == blank + assign compare_at_price = product.price + endif + endif + endif + comment + end Yagi app code + endcomment + + assign money_price = price | money + assign money_price_min = price_min | money + assign money_price_max = price_max | money + if settings.currency_code_enabled + assign money_price = price | money_with_currency + assign money_price_min = price_min | money_with_currency + assign money_price_max = price_max | money_with_currency + endif + + if target == product and product.price_varies + assign money_price = 'products.product.price.from_price_html' | t: price: money_price + endif +-%} + +{%- unless target == null and placeholder == null -%} +
+
+ {%- comment -%} + Explanation of description list: + - div.price__regular: Displayed when there are no variants on sale + - div.price__sale: Displayed when a variant is a sale + {%- endcomment -%} +
+ {%- if product.quantity_price_breaks_configured? -%} + {%- if show_compare_at_price and compare_at_price -%} + {%- unless product.price_varies == false and product.compare_at_price_varies %} + + {{- 'products.product.price.regular_price' | t -}} + + + + {% if settings.currency_code_enabled %} + {{ compare_at_price | money_with_currency }} + {% else %} + {{ compare_at_price | money }} + {% endif %} + + + {%- endunless -%} + {%- endif -%} + {{ 'products.product.price.regular_price' | t }} + + {{- + 'products.product.volume_pricing.price_range' + | t: minimum: money_price_min, maximum: money_price_max + -}} + + {%- else -%} + {{ 'products.product.price.regular_price' | t }} + + {{ money_price }} + + {%- endif -%} +
+
+ {%- unless product.price_varies == false and product.compare_at_price_varies %} + {{ 'products.product.price.regular_price' | t }} + + + {% if settings.currency_code_enabled %} + {{ compare_at_price | money_with_currency }} + {% else %} + {{ compare_at_price | money }} + {% endif %} + + + {%- endunless -%} + {{ 'products.product.price.sale_price' | t }} + + {{ money_price }} + +
+ + {{ 'products.product.price.unit_price' | t }} + + {{- product.selected_or_first_available_variant.unit_price | money -}} + +  {{ 'accessibility.unit_price_separator' | t }}  + + {%- if product.selected_or_first_available_variant.unit_price_measurement.reference_value != 1 -%} + {{- product.selected_or_first_available_variant.unit_price_measurement.reference_value -}} + {%- endif -%} + {{ product.selected_or_first_available_variant.unit_price_measurement.reference_unit }} + + + +
+ {%- if show_badges -%} + {% if settings.dbtfy_discount_saved %} + {% render 'dbtfy-discount-saved', product_compare_price: compare_at_price, product_price: price %} + {% else %} + + {%- if settings.sale_badge_text != blank -%} + {{- settings.sale_badge_text -}} + {%- else -%} + {{- 'products.product.on_sale' | t -}} + {%- endif -%} + + {% endif %} + + + {%- if settings.sold_out_badge_text != blank -%} + {{- settings.sold_out_badge_text -}} + {%- else -%} + {{- 'products.product.sold_out' | t -}} + {%- endif -%} + + {%- endif -%} +
+{% endunless %}