使用 Shopify Liquid 元字段的变体相关产品
Related products by variant using metafields for Shopify Liquid
我正在尝试在 caroline 的相关产品解决方案的基础上构建具有元字段的相关产品变体。也就是说,当您单击桌子的白色变体时,您会看到椅子的白色变体作为相关产品。 (与无论变体如何都将桌面产品链接到椅子产品相反。)Caroline 的解决方案在这里:https://gist.github.com/carolineschnapp/1003334 下面是我的代码。 Right now it's putting the same product twice on page load, and nothing happens when a different vairant is selected.我为每个变体格式化元字段值的方式是放置 "related-product-handle-1, variant-id-1, related-product-handle-2,variant-id-2, related-product-handle-3, variant-id-3" 而不仅仅是产品句柄。
{% assign image_size = 'compact' %}
{% assign heading = 'Related Products' %}
{% if product.selected_or_first_available_variant.metafields.recommendations.productHandles %}
<h3>{{ heading }}</h3>
<ul class="related-products"></ul>
{% endif %}
<script>!window.jQuery && document.write('<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"><\/script>')</script>
{{ 'api.jquery.js' | shopify_asset_url | script_tag }}
<script type="text/javascript" charset="utf-8">
$(document).ready(function(){
setTimeout(function() {
var dd = $('.single-option-selector#product-select-option-0');
var vId = location.search.substring(9);
switchRelated(vId);
dd.on('change', function() {
$('ul.related-products').empty();
var vId = location.search.substring(9);
switchRelated(vId);
});
function switchRelated(vId) {
var list = $('ul.related-products');
var vIdd = parseInt(vId);
{% for variant in product.variants %}
{% if variantId == vIdd %}
{% if variant.metafields.recommendations.productHandles %}
recommendations = jQuery.trim({{ variant.metafields.recommendations.productHandles | json }}).split(/[\s,;]+/);
for (var i=0; i < (recommendations.length); i+=2 ) {
var j = (i + 1);
if (recommendations.length && recommendations[i] && recommendations[j] !== '') {
jQuery.getJSON('/products/' + recommendations[i] + '.js', function(product) {
product.variants.forEach(function(variant) {
if (variant.id == parseInt(recommendations[j])) {
list.append('<li><div class="image"><a href="' + product.url + '?variant=' + recommendations[j] +'"><img src="' + variant.featured_image.src + '" /></a></div><h4><a href="' + product.url + '?variant=' + recommendations[j] + '">' + product.title + '</a></h4></li>');
}
});
});
}
}
{% endif %}
{% endif %}
{% endfor %}
}
}, 1);
});
</script>
答案已编辑:第一个非常有用,一旦我对语法错误进行了一些更正并添加了一些简短的内容。这是我为可能需要的人编辑的答案版本:
Product.liquid:
{% for variant in product.variants %}
{% capture metafield_data %}{% endcapture %}
{% assign related_products = variant.metafields.recommendations.productHandles | split: '|' %}
{% for related_product in related_products %}
{% assign metafield_items = related_product | split: ',' %}
{% assign r_p = metafield_items[0] %}
{% assign r_v = metafield_items[1] | plus: 0 %}
{% assign r_n = all_products[r_p].title %}
{% for related_variant in all_products[r_p].variants %}
{% if related_variant.id == r_v %}
{% assign r_i = related_variant.image.src | img_url: 'small' %}
{% endif %}
{% endfor %}
{% capture metafield_data %}{{metafield_data}}{{ r_p }},{{ r_v }},{{ r_i }},{{ r_n }}{% unless forloop.last %}|{% endunless %}{% endcapture %}
{% endfor %}
<option id="{{ variant.id }}" data-metafield="{{ metafield_data }}" {% if variant == product.selected_or_first_available_variant %} selected="selected" {% endif %} value="{{ variant.id }}">{{ variant.title }} - {{ variant.price | money }}- {{ related_products.size }}</option>
{% endfor %}
和相关变体 javascript 片段:
$(document).ready(function(){
setTimeout(function() {
var dd = $('.single-option-selector#product-select-option-0');
if(location.search.substring(9) != ''){
var vId = location.search.substring(9);
}
else {
var vId = {{ product.selected_or_first_available_variant.id }};
}
switchRelated(vId);
$('#product-select option').each(function(index, element){
$(".single-option-selector#product-select-option-0 option:eq(" + index + ")").attr('id', element.id);
$('.single-option-selector#product-select-option-0 option:eq(' + index + ')').attr('data-metafield', $(element).attr("data-metafield"));
$('#product-select option:eq(' + index + ')').attr('id', '');
});
dd.on('change', function() {
var list = $('ul.related-products');
$(list).children().remove();
$(list).empty();
if(location.search.substring(9) != ''){
var vId = location.search.substring(9);
}
else {
var vId = {{ product.selected_or_first_available_variant.id }};
}
switchRelated(vId);
});
function switchRelated(vId) {
var list = $('ul.related-products');
$(list).children().remove();
$(list).empty();
var vIdd = parseInt(vId);
console.log(vIdd)
var variant_matches = $('#' + vId).attr('data-metafield').split('|');
for (var i=0; i < variant_matches.length; i++) {
var items = variant_matches[i].split(',');
list.append('<li><div class="image"><a href="/products/'+items[0]+'/?variant='+items[1]+'"><img src="'+items[2]+'" /></a></div><h4><a href="/products/' + items[0] + '?variant=' + items[2] + '">' + items[3].replace('_','') + '</a></h4></li>');
}
}
}, 1);
});
我唯一担心的是我正在将数据从 'product-select' 下拉列表复制到 'single-option-selector' 下拉列表。我这样做是因为没有用于呈现单选项选择器的模板,它似乎是通过 javascript 添加的。如果有人对在 liquid 中操纵单选项选择器有任何见解,请告诉我。谢谢!!
最快的实现方式是让 Shopify 服务器构建元素,以便通过任何 AJAX 调用拉取链接和图像 URL。方法如下。
根据您的 productHandles 示例,我猜测列表中的 3 项与特定变体 ID xxxxxx
相关。以这种方式构造元字段值
rph-1,rph-v-id-1|rph-2,rph-v-id-2|rph-3,rph-v-id-3
现在在产品液体中找到这个部分
<select class="product-select" id="product-select" name="id" .... </select>
把里面的html改成下面那个-
{% for variant in product.variants %}
{% assign related_products = variant.metafields.recommendations.productHandles | split: '|' %}
{% for related_product in related_products %}
{% assign metafield_items = related_product | split: ',' %}
{% assign r_p = metafield_items[0] %}
{% assign r_v = metafield_items[1] | plus: 0 %} {% comment %} converting string to number {% endcomment %}
{% assign r_n = all_products[r_p].title | replace: ' ','_' %}
{% for related_variant in all_products[r_p].variants %}
{% if related_variant.id == r_v %} {% comment %} fails if r_v is a string {% endcomment %}
{% assign r_i = related_variant.image.src }}
{% endif %}
{% endfor %}
{% capture metafield_data %}{{metafield_data}}{{ r_p }},{{ r_v }},{{ r_i }},{{ r_n }}{% unless forloop.last %}|{% endunless %}{% endcapture %}
{% endfor %}
<option id="{{ variant.id }}" metafield-data={{ metafield_data }}{% if variant == product.selected_or_first_available_variant %} selected="selected" {% endif %} value="{{ variant.id }}">{{ variant.title }} - {{ variant.price | money }}</option>
{% endfor %}
"metafield_data" 将包含所有相关产品信息(产品、变体、变体图像)。
JS 替换 "switchRelated(vId)"
function switchRelated(vId) {
var list = $('ul.related-products');
var vIdd = parseInt(vId);
list.children().remove()
var variant_matches = $('#vId').attr('metafield-data').split('|')
for (var i=0; i < variant_matches.length; i++) {
var items = variant_matches[i].split(',')
list.append('<li><div class="image"><a href="/products/'+items[0]+'/?variant='+items[1]+'"><img src="'+items[2]+'" /></a></div><h4><a href="/products/'+items[0]+'?variant='item[2]'">'+items[3].replace('_','')+'</a></h4></li>');
}
}
通俗地说,您是从元字段中获取产品句柄和变体 ID,并使用 liquid(服务器端功能)向它们添加标题和图像。然后,您将它们与变体进行匹配,并在您再次使用的元素中分配一个数据变量来更改 html 元素。
P.S。代码很长而且没有正确对齐,我可能在这里和那里漏掉了代码标点符号。请检查它们。逻辑很简单,AJAX 的全部权重被移除并转移到正常的 HTML 调用。
我正在尝试在 caroline 的相关产品解决方案的基础上构建具有元字段的相关产品变体。也就是说,当您单击桌子的白色变体时,您会看到椅子的白色变体作为相关产品。 (与无论变体如何都将桌面产品链接到椅子产品相反。)Caroline 的解决方案在这里:https://gist.github.com/carolineschnapp/1003334 下面是我的代码。 Right now it's putting the same product twice on page load, and nothing happens when a different vairant is selected.我为每个变体格式化元字段值的方式是放置 "related-product-handle-1, variant-id-1, related-product-handle-2,variant-id-2, related-product-handle-3, variant-id-3" 而不仅仅是产品句柄。
{% assign image_size = 'compact' %}
{% assign heading = 'Related Products' %}
{% if product.selected_or_first_available_variant.metafields.recommendations.productHandles %}
<h3>{{ heading }}</h3>
<ul class="related-products"></ul>
{% endif %}
<script>!window.jQuery && document.write('<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"><\/script>')</script>
{{ 'api.jquery.js' | shopify_asset_url | script_tag }}
<script type="text/javascript" charset="utf-8">
$(document).ready(function(){
setTimeout(function() {
var dd = $('.single-option-selector#product-select-option-0');
var vId = location.search.substring(9);
switchRelated(vId);
dd.on('change', function() {
$('ul.related-products').empty();
var vId = location.search.substring(9);
switchRelated(vId);
});
function switchRelated(vId) {
var list = $('ul.related-products');
var vIdd = parseInt(vId);
{% for variant in product.variants %}
{% if variantId == vIdd %}
{% if variant.metafields.recommendations.productHandles %}
recommendations = jQuery.trim({{ variant.metafields.recommendations.productHandles | json }}).split(/[\s,;]+/);
for (var i=0; i < (recommendations.length); i+=2 ) {
var j = (i + 1);
if (recommendations.length && recommendations[i] && recommendations[j] !== '') {
jQuery.getJSON('/products/' + recommendations[i] + '.js', function(product) {
product.variants.forEach(function(variant) {
if (variant.id == parseInt(recommendations[j])) {
list.append('<li><div class="image"><a href="' + product.url + '?variant=' + recommendations[j] +'"><img src="' + variant.featured_image.src + '" /></a></div><h4><a href="' + product.url + '?variant=' + recommendations[j] + '">' + product.title + '</a></h4></li>');
}
});
});
}
}
{% endif %}
{% endif %}
{% endfor %}
}
}, 1);
});
</script>
答案已编辑:第一个非常有用,一旦我对语法错误进行了一些更正并添加了一些简短的内容。这是我为可能需要的人编辑的答案版本:
Product.liquid:
{% for variant in product.variants %}
{% capture metafield_data %}{% endcapture %}
{% assign related_products = variant.metafields.recommendations.productHandles | split: '|' %}
{% for related_product in related_products %}
{% assign metafield_items = related_product | split: ',' %}
{% assign r_p = metafield_items[0] %}
{% assign r_v = metafield_items[1] | plus: 0 %}
{% assign r_n = all_products[r_p].title %}
{% for related_variant in all_products[r_p].variants %}
{% if related_variant.id == r_v %}
{% assign r_i = related_variant.image.src | img_url: 'small' %}
{% endif %}
{% endfor %}
{% capture metafield_data %}{{metafield_data}}{{ r_p }},{{ r_v }},{{ r_i }},{{ r_n }}{% unless forloop.last %}|{% endunless %}{% endcapture %}
{% endfor %}
<option id="{{ variant.id }}" data-metafield="{{ metafield_data }}" {% if variant == product.selected_or_first_available_variant %} selected="selected" {% endif %} value="{{ variant.id }}">{{ variant.title }} - {{ variant.price | money }}- {{ related_products.size }}</option>
{% endfor %}
和相关变体 javascript 片段:
$(document).ready(function(){
setTimeout(function() {
var dd = $('.single-option-selector#product-select-option-0');
if(location.search.substring(9) != ''){
var vId = location.search.substring(9);
}
else {
var vId = {{ product.selected_or_first_available_variant.id }};
}
switchRelated(vId);
$('#product-select option').each(function(index, element){
$(".single-option-selector#product-select-option-0 option:eq(" + index + ")").attr('id', element.id);
$('.single-option-selector#product-select-option-0 option:eq(' + index + ')').attr('data-metafield', $(element).attr("data-metafield"));
$('#product-select option:eq(' + index + ')').attr('id', '');
});
dd.on('change', function() {
var list = $('ul.related-products');
$(list).children().remove();
$(list).empty();
if(location.search.substring(9) != ''){
var vId = location.search.substring(9);
}
else {
var vId = {{ product.selected_or_first_available_variant.id }};
}
switchRelated(vId);
});
function switchRelated(vId) {
var list = $('ul.related-products');
$(list).children().remove();
$(list).empty();
var vIdd = parseInt(vId);
console.log(vIdd)
var variant_matches = $('#' + vId).attr('data-metafield').split('|');
for (var i=0; i < variant_matches.length; i++) {
var items = variant_matches[i].split(',');
list.append('<li><div class="image"><a href="/products/'+items[0]+'/?variant='+items[1]+'"><img src="'+items[2]+'" /></a></div><h4><a href="/products/' + items[0] + '?variant=' + items[2] + '">' + items[3].replace('_','') + '</a></h4></li>');
}
}
}, 1);
});
我唯一担心的是我正在将数据从 'product-select' 下拉列表复制到 'single-option-selector' 下拉列表。我这样做是因为没有用于呈现单选项选择器的模板,它似乎是通过 javascript 添加的。如果有人对在 liquid 中操纵单选项选择器有任何见解,请告诉我。谢谢!!
最快的实现方式是让 Shopify 服务器构建元素,以便通过任何 AJAX 调用拉取链接和图像 URL。方法如下。
根据您的 productHandles 示例,我猜测列表中的 3 项与特定变体 ID xxxxxx
相关。以这种方式构造元字段值
rph-1,rph-v-id-1|rph-2,rph-v-id-2|rph-3,rph-v-id-3
现在在产品液体中找到这个部分
<select class="product-select" id="product-select" name="id" .... </select>
把里面的html改成下面那个-
{% for variant in product.variants %}
{% assign related_products = variant.metafields.recommendations.productHandles | split: '|' %}
{% for related_product in related_products %}
{% assign metafield_items = related_product | split: ',' %}
{% assign r_p = metafield_items[0] %}
{% assign r_v = metafield_items[1] | plus: 0 %} {% comment %} converting string to number {% endcomment %}
{% assign r_n = all_products[r_p].title | replace: ' ','_' %}
{% for related_variant in all_products[r_p].variants %}
{% if related_variant.id == r_v %} {% comment %} fails if r_v is a string {% endcomment %}
{% assign r_i = related_variant.image.src }}
{% endif %}
{% endfor %}
{% capture metafield_data %}{{metafield_data}}{{ r_p }},{{ r_v }},{{ r_i }},{{ r_n }}{% unless forloop.last %}|{% endunless %}{% endcapture %}
{% endfor %}
<option id="{{ variant.id }}" metafield-data={{ metafield_data }}{% if variant == product.selected_or_first_available_variant %} selected="selected" {% endif %} value="{{ variant.id }}">{{ variant.title }} - {{ variant.price | money }}</option>
{% endfor %}
"metafield_data" 将包含所有相关产品信息(产品、变体、变体图像)。
JS 替换 "switchRelated(vId)"
function switchRelated(vId) {
var list = $('ul.related-products');
var vIdd = parseInt(vId);
list.children().remove()
var variant_matches = $('#vId').attr('metafield-data').split('|')
for (var i=0; i < variant_matches.length; i++) {
var items = variant_matches[i].split(',')
list.append('<li><div class="image"><a href="/products/'+items[0]+'/?variant='+items[1]+'"><img src="'+items[2]+'" /></a></div><h4><a href="/products/'+items[0]+'?variant='item[2]'">'+items[3].replace('_','')+'</a></h4></li>');
}
}
通俗地说,您是从元字段中获取产品句柄和变体 ID,并使用 liquid(服务器端功能)向它们添加标题和图像。然后,您将它们与变体进行匹配,并在您再次使用的元素中分配一个数据变量来更改 html 元素。
P.S。代码很长而且没有正确对齐,我可能在这里和那里漏掉了代码标点符号。请检查它们。逻辑很简单,AJAX 的全部权重被移除并转移到正常的 HTML 调用。