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

发布于 2025-01-11 11:11:30 字数 1530 浏览 0 评论 0原文

我已经探索和测试了几个小时如何从特定产品句柄检索元字段值。

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

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

我正在寻求某人的帮助,从本质上为我指明如何实现我正在寻找的目标的方向。

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);

        //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 }}

I've been exploring and testing for hours how to retrieve the metafield values from a specific product handle.

I've tested using AJAX calls and using getJSON neither of which have had any success with all seem to throw the same error.

I'm aware that you most definitely can't access the product metafields directly as they're somewhat protected and therefore are excluded from the usual handle.js file I'm currently successfully able to get.

I am seeking someones help to essentially point me in the direction of how to accomplish what I'm looking for.

product-view.js file

$(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 file

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

墨落画卷 2025-01-18 11:11:30

因此,我最终找到了一个网站,该网站使用了他们所描述的“黑客”方式,因为他们不相信这是 {% 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>

然后,您可以从用于访问产品对象的 javascript 文件访问 dishMetaFields定义的元字段应该是句柄 匹配。

产品视图.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;
        });
    });
}

So I managed to find a website finally that used what they described as a 'hack' because they don't believe this is the way that {% capture %} however, it did achieve the require outcome that I needed and hopefully is useful for others in future:

theme.liquid file

{% 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>

You can then access the dishMetaFields from the javascript file you're using to access the product object to get the defined metafields should the handles match.

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;
        });
    });
}
紙鸢 2025-01-18 11:11:30

您也可以按照最初的方法这样做。在这种情况下,您不需要迭代集合的所有元字段,而只需迭代所需的产品。从性能上来说,这应该是比较好的。想法是相同的,您在 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))         
});

You can also do it like this following your initial approach. In this scenario, you don't need to iterate over all metafields of a collection but only for the required product. This should be better comparatively in terms of performance. The idea is same, that you generate the JSON object in Liquid snippet and then parse the JSON in JavaScript.

{% 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 %}
}

And for JavaScript part, use simple GET and then parse the response.

jQuery.get('/products/' + product_handle + '?view=metafield', function (product) {
  console.log(product)
  console.log(JSON.parse(product))         
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文