Необходима мудрость Javascript.
Мне нужен способ создания массива продуктов для Гугл АналитикаdataLayer при использовании Django в качестве бэкенда и отправке переменной {{ order_items }} в шаблон 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
dataLayerthat is going to use afterwards to capture values for Google Analytics, via Google Tag Manager.
Я использую Django для серверной части и отправляю эти переменные во внешний интерфейс:
{{order}}
{{order_items}}
И сказал, что этот массив должен быть внутри другого «родительского» массива, согласно этому сообщению в блоге от Эксперт Google Аналитики:
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({



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Да, я бы сказал, это хорошая практика. Я предполагаю, что 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
});
});
Мне пришлось удалить покупку в window.dataLayer.ecommerce.purchase.products.push({, так как товара нет внутри покупки, и я получал сообщение об ошибке.
Вы не можете передавать данные непосредственно в выбранный ключ слоя данных. Вам нужно отправить данные в сам dataLayer:
dataLayer.push({...});
Для вашего конкретного случая также лучше поместить все данные о продукте в запрос о покупке в один 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'
Использование события в начальном вызове может по-прежнему работать (не проверялось), но оно уже может быть обработано с помощью события просмотра страницы.
Итак, вопрос заключался в создании массива продуктов (в Javascript) из списка Python (или массива на других языках).
Сложность вопроса заключалась в том, что я (владелец вопроса) не понимал, как работать со списком 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 %}
у меня не работает. Ошибка: Uncaught ReferenceError: order_items не определен, я думаю, это связано с тем, что вы обращаетесь к переменным Django в html, например: {{ order_items }}