Shopify 使用 JS/jQuery 获取产品的元字段值

Shopify get meta field value of product using JS/jQuery

几个小时以来,我一直在探索和测试如何从特定产品句柄中检索元字段值。

我已经使用 AJAX 调用和使用 getJSON 进行了测试,但两者都没有成功,似乎都抛出相同的错误。

我知道您绝对不能直接访问产品元字段,因为它们在某种程度上受到保护,因此被排除在我目前能够成功获取的常用 handle.js 文件之外。

我正在寻求某人的帮助,从根本上为我指出如何完成我正在寻找的目标的方向。

产品-view.js文件

$(document).ready(function () {
    $.getScript("//cdnjs.cloudflare.com/ajax/libs/fancybox/2.1.5/jquery.fancybox.min.js").done(function() {
        createProductData();
    });
});

function createProductData() {
    $(".product-view").click(function () {
        if ($('#product-view').length == 0){
            $("body").append('<div id="product-view"></div>');
        }

        var product_handle = $(this).data('handle');

        $('#product-view').addClass(product_handle);

        //Default Product Fields
        jQuery.getJSON('/products/' + product_handle + '.js', function (product) {
            var images = product.images;
            var title = product.title;
            var price = product.price;
            var desc = product.description;
        });

        //Product Meta Fields
        jQuery.getJSON('/products/' + product_handle + '?view=metafields.json', function (product) {
            var dish_type = product.metafields.arena.dish;
            console.log(dish_type);
            //error: Cannot read properties of undefined (reading 'arena')
        });
    });
}

product.metafields.liquid 文件

{% layout none %}
{{ product.metafields.arena | json }}

所以我最终找到了一个使用他们描述为 'hack' 的网站,因为他们不相信这是 {% capture %} 的方式,但是,它确实达到了要求的结果我需要并且希望将来对其他人有用:

theme.liquid 文件

{% capture 'dishMetaFields' %}
    {
        {% for product in collections["all-dishes"].products %}

            "{{ product.handle }}" : {
                product_chinese_title : "{{product.metafields.arena.chinese_title}}",
                product_feeds : "{{product.metafields.arena.feeds}}",
                product_spice_level : "{{product.metafields.arena.spice}}",
                product_dish : "{{product.metafields.arena.dish}}",
                product_proteins : "{{product.metafields.arena._proteins}}",
                product_diet : "{{product.metafields.arena._diet}}",
                product_cooking_time : "{{product.metafields.arena._diet}}",
                product_cooking_video : "{{product.metafields.arena._method_video}}",
                product_cooking_text : "{{product.metafields.arena._method}}",
                product_nutrients : "{{product.metafields.arena._nutrition}}",
                product_allergies : "{{product.metafields.arena._allergies}}",
                {% unless product.metafields.arena._bundle_dishes == blank %}
                    {%- assign dishCounter = 1 -%}
                    product_bundle_dish : {
                        {% for value in product.metafields.arena._bundle_dishes %}
                            "dish-{{ dishCounter }}" : "{{ value }}",
                            {%- assign dishCounter = dishCounter | plus:1 -%}
                        {% endfor %}
                    }
                {% endunless %}
            },
        
        {% endfor %}
    }
{% endcapture %}

<script type = "text/javascript">
  let dishMetaFields = {{ dishMetaFields }}
</script>

然后您可以从您用于访问产品对象的 dishMetaFields 文件访问 dishMetaFields,以在句柄匹配时获取定义的元字段。

product-view.js

$(document).ready(function () {
    $.getScript("//cdnjs.cloudflare.com/ajax/libs/fancybox/2.1.5/jquery.fancybox.min.js").done(function() {
        createProductData();
    });
});

function createProductData() {
    $(".product-view").click(function () {
        if ($('#product-view').length == 0){
            $("body").append('<div id="product-view"></div>');
        }

        var product_handle = $(this).data('handle');

        $('#product-view').addClass(product_handle);

        jQuery.getJSON('/products/' + product_handle + '.js', function (product) {
            //Default Product Fields
            var images = product.images;
            var title = product.title;
            var price = product.price;
            var desc = product.description;

            //Product Meta Fields
            var metafields = dishMetaFields[product_handle];
            var dish_type = metafields.product_dish;
        });
    });
}

您也可以按照您的初始方法这样做。在这种情况下,您不需要遍历集合的所有元字段,而只需遍历所需的产品。这在性能方面应该比较好。想法是一样的,您在 Liquid 片段中生成 JSON 对象,然后在 JavaScript.

中解析 JSON
{% layout none %}
{
    "product_chinese_title" : "{{product.metafields.arena.chinese_title}}",
    "product_feeds" : "{{product.metafields.arena.feeds}}",
    "product_spice_level" : "{{product.metafields.arena.spice}}",
    "product_dish" : "{{product.metafields.arena.dish}}",
    "product_proteins" : "{{product.metafields.arena._proteins}}",
    "product_diet" : "{{product.metafields.arena._diet}}",
    "product_cooking_time" : "{{product.metafields.arena._diet}}",
    "product_cooking_video" : "{{product.metafields.arena._method_video}}",
    "product_cooking_text" : "{{product.metafields.arena._method}}",
    "product_nutrients" : "{{product.metafields.arena._nutrition}}",
    "product_allergies" : "{{product.metafields.arena._allergies}}"
    {% unless product.metafields.arena._bundle_dishes == blank %}
        ,
        {%- assign dishCounter = 1 -%}
        "product_bundle_dish" : {
            {% for value in product.metafields.arena._bundle_dishes %}
                "dish-{{ dishCounter }}" : "{{ value }}"
                 {% if forloop.last == false %}
                    ,
                 {% endif %}
                 {%- assign dishCounter = dishCounter | plus:1 -%}
            {% endfor %}
                    }
    {% endunless %}
}

对于 JavaScript 部分,使用简单的 GET 然后解析响应。

jQuery.get('/products/' + product_handle + '?view=metafield', function (product) {
  console.log(product)
  console.log(JSON.parse(product))         
});