JS:如何为 Google Analytics dataLayer 生成产品数组?

JS: how generate the product array for Google Analytics dataLayer?

Javascript 需要智慧。

当使用 Django 作为后端并发送 {{ order_items }} 变量时,我需要一种为 Google Analytics dataLayer 生成产品数组的方法至 thank_you_page.html 模板:

products: [{
            id: 'product_id',
            name: 'Product A',
            price: '24.00',
            quantity: 1,
            coupon: 'FOR20'
          },{
            id: 'another_product_id',
            name: 'MY ADD-ON',
            price: '1.00',
            quantity: 1,
            coupon: 'ADD-ONS OFF'
          }]

It is going to be part of a dataLayer that is going to use afterwards to capture values for Google Analytics, via Google Tag Manager.

我在后端使用 Django,并将此变量发送到前端:

{{order}}

{{order_items}}

并且之前说过这个数组必须在另一个 "parent" 数组中,根据这个博客 post 来自 Google Analytics Expert:

window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  event: 'eec.purchase',
  ecommerce: {
    currencyCode: 'EUR',
    purchase: {
      actionField: {
        id: 'ORDER12345',
        affiliation: 'Simo\'s shop',
        revenue: '11.00',
        tax: '1.00',
        shipping: '2.00',
        coupon: 'SUMMER2019'
      },
      products: [{
            id: 'product_id',
            name: 'Product A',
            price: '24.00',
            quantity: 1,
            coupon: 'FOR20'
          },{
        id: 'another_product_id',
        name: 'MY ADD-ON',
        price: '1.00',
        quantity: 1,
        coupon: 'ADD-ONS OFF'
      }]
    }
  }
});

我应该放一个空的products = [],然后做for循环把元素压入里面吗?

products = []
{% for item in order_items %}
   products.push({
     id: item.id,
     name: item.name,
     price: item.price,
     quantity: item.quantity,
     coupon: item.coupon
   });
{% endfor %}

更新 1:

使用此代码:

{% block data_layer %}
    <script>
        window.dataLayer = window.dataLayer || [];
        window.dataLayer.push({
            event: 'eec.purchase',
            ecommerce: {
                currencyCode: 'PEN',
                purchase: {
                    actionField: {
                        id: {{ order_number }},
                        affiliation: 'Stickers Gallito E-Commerce',
                        revenue: {{ total }},
                        shipping: {{ costo_despacho }},
                        coupon: 'SUMMER2019'
                    }
                },
                products: []
            }
        });
    </script>


    {% for item in order_items %}
        <script>
            window.dataLayer.ecommerce.products.push({
                id: item.order.id,
                name: item.name,
                price: item.price,
                quantity: item.quantity
            });
        </script>
    {% endfor %}



{% endblock %}

出现错误:

Uncaught TypeError: Cannot read property 'products' of undefined at (index):72

这是第 72 行:

 window.dataLayer.ecommerce.products.push({

是的,我会说,这是很好的做法。我假设 order_items 是一个项目数组。

window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  event: 'eec.purchase',
  ecommerce: {
    currencyCode: 'EUR',
    purchase: {
      actionField: {
        id: 'ORDER12345',
        affiliation: 'Simo\'s shop',
        revenue: '11.00',
        tax: '1.00',
        shipping: '2.00',
        coupon: 'SUMMER2019'
      }
    },
    products: []
  }
});

然后使用 forEach 将项目推送到产品中。

 order_items.forEach(item => {
   window.dataLayer.ecommerce.purchase.products.push({
     id: item.id,
     name: item.name,
     price: item.price,
     quantity: item.quantity,
     coupon: item.coupon
   });
 });

您不能将数据直接推送到数据层的选定键中。您需要将数据推送到 dataLayer 本身:

dataLayer.push({...});

对于你的具体情况,将purchase call的所有产品数据都放在一个push中也是比较好的做法,因为你需要一起处理,这样GTM就不知道了,这是最后一个产品,当产品数组被认为准备就绪时。

所以我的建议是循环产品,并将它们作为对象数组放入产品中,正如增强型电子商务数据所期望的那样:

{% block data_layer %}
    <script>
        window.dataLayer = window.dataLayer || [];
        window.dataLayer.push({
            event: 'eec.purchase',
            ecommerce: {
                currencyCode: 'PEN',
                purchase: {
                    actionField: {
                        id: {{ order_number }},
                        affiliation: 'Stickers Gallito E-Commerce',
                        revenue: {{ total }},
                        shipping: {{ costo_despacho }},
                        coupon: 'SUMMER2019'
                    }
                },
                products: [

    {% for item in order_items %}
                  {
                    id: item.order.id,
                    name: item.name,
                    price: item.price,
                    quantity: item.quantity
                  },
    {% endfor %}
                ]
            }
        });
    </script>
{% endblock %}

另请注意,此初始化通常在调用 GTM 基本代码之前使用:

window.dataLayer = window.dataLayer || [];

而事件通常是在稍后的数据推送中指定的,为了让 GTM 对这个特定事件采取行动:

event: 'eec.purchase'

在初始调用中使用事件可能仍然有效(尚未测试),但它也已经可以使用页面查看事件进行处理。

所以问题是关于从 Python 列表(或其他语言的数组)创建产品数组(在 Javascript 中)。

问题的复杂性是因为我(问题的​​所有者)不明白如何使用模板中的python列表来生成一个 javascript 数组。

答案是您需要使用序列化程序将 python list 发送到模板:

def thanks_deposit_payment(request):
    order_number = Order.objects.latest('id').id

    total = Order.objects.latest('id').total

    costo_despacho = Order.objects.latest('id').shipping_cost

    order_items = OrderItem.objects.filter(order=Order.objects.latest('id'))


    order_items = serialize('json', order_items, fields=['id', 'sku', 'product', 'price', 'size', 'quantity'])

    response = render(request, 'thanks_deposit_payment.html', dict(order_number=order_number, total=total,
                                                                   order_items=order_items, costo_despacho=costo_despacho))
    return response

thanks_deposit_payment.html模板中,你必须使用JSON:

像这样:products: JSON.parse('{{ order_items | safe }}')

{% block data_layer %}

    <script>
        window.dataLayer = window.dataLayer || [];
        window.dataLayer.push({
            event: 'eec.purchase',
            ecommerce: {
                currencyCode: 'PEN',
                purchase: {
                    actionField: {
                        id: {{ order_number }},
                        affiliation: 'Stickers Gallito E-Commerce',
                        revenue: {{ total }},
                        shipping: {{ costo_despacho }},
                        coupon: ''
                    },
                    products: JSON.parse('{{ order_items | safe }}')
                },

            }
        });
    </script>

{% endblock %}