I have been updating our various websites to Google Analytics 4 over the past couple of months, and I've started working on the Shopify store. I've added an ecommerce dataLayer push in a liquid file within the Sections folder, but the dataLayer doesn't get updated. It's a simple view_item event, and I've checked and double-checked for typos. As a test, I replaced the ecommerce dataLayer push with a test_event with dummy data, which fired as expected.
Is there something I'm missing here? Why won't Shopify allow my ecommerce push to the dataLayer?
dataLayer.push({ ecommerce: null });
dataLayer.push({
event: "view_item",
ecommerce: {
currency: {{ shop.currency }},
value: {{ product.price | minus: discount.amount | money_without_currency }},
items: [
{
item_id: {{ product.id }},
item_name: {{ product.title }},
affiliation: "Shopify",
coupon: {{ discount.title }},
discount: {{ discount.amount | money_without_currency }},
index: 0,
item_category: "Products",
item_category2: {{ product.type }},
item_list_id: "related_products",
item_list_name: "Related Products",
price: {{ product.price | money_without_currency }},
quantity: 1
}
]
}
});
I am using Google Tag Manager, but I can't get the dataLayer to update with the ecommerce event.
dataLayer.push({ ecommerce: null });
That word, "null", means you're cancelling the dataLayer; so, that's why it won't work. You need to remove that line to get it to work.
For anyone who might stumble onto this question, I believe I've found the issue. It's a simple case of syntax. The liquid variables which output strings need to be enclosed in quotes.
I also added conditional statements to prevent some name-value pairs from appearing with no values.
dataLayer.push({ ecommerce: null });
dataLayer.push({
event: 'view_item',
ecommerce: {
currency: '{{ shop.currency }}',
value: {{ product.price | minus: discount.amount | money_without_currency }},
items: [{
item_id: '{{ product.id }}',
item_name: '{{ product.title }}',
affiliation: 'Shopify',
{% if discount %}
coupon: '{{ discount.title }}',
discount: {{ discount.amount | money_without_currency }},
{% endif %}
index: 0,
item_category: 'Products',
{% if product.type %}
item_category2: '{{ product.type }}',
{% endif %}
price: {{ product.price | money_without_currency }},
quantity: 1
}]
}
});
Related
I've been working with generating some JSON data from liquid tags, it seems that excluding the last comma in this JSON data is not happening when nesting 'unless' tags.
Please see answer below, this initial issue and question was not the problem.
<script id="suggest-json" type="application/json">
[
{%- for item in site[page.collection] -%}
{%- unless item.url == page.url -%}
{% assign images = item.media | where: "type", "image" %}
{% assign image = images.first %}
{
"url": "{{site.baseurl}}{{ item.url }}",
"title": "{{ item.title }}",
"subject": "{{ item.game }}",
"image": "{{ image.thumbnail }}",
"alt": "{{ image.thumbnail_alt }}"
} {%- unless forloop.last -%},{%- endunless -%}
{%- endunless -%}
{%- endfor -%}
]
</script>
Undesired Output (The last comma is invalidating the Json):
[
{
"url": "/portfolio/levels/low-life/",
"title": "Low-Life",
"subject": "Final Verdikt: Source",
"image": "https://picsum.photos/445/296?random=1",
"alt": "Image 1"
},
{
"url": "/portfolio/levels/prospekt/",
"title": "Prospekt",
"subject": "Final Verdikt: Source",
"image": "https://picsum.photos/445/296?random=1",
"alt": "Image 1"
},
{
"url": "/portfolio/levels/station/",
"title": "Station",
"subject": "Half-Life 2: Opposition",
"image": "https://picsum.photos/445/296?random=1",
"alt": "Image 1"
},
{
"url": "/portfolio/levels/dredge/",
"title": "Dredge",
"subject": "Firearms: Source",
"image": "https://picsum.photos/445/296?random=1",
"alt": "Image 1"
},
{
"url": "/portfolio/levels/gravitas/",
"title": "Gravitas",
"subject": "Firearms: Source",
"image": "https://picsum.photos/445/296?random=1",
"alt": "Image 1"
},
{
"url": "/portfolio/levels/navarro/",
"title": "Navarro",
"subject": "Firearms: Source",
"image": "https://picsum.photos/445/296?random=1",
"alt": "Image 1"
},
{
"url": "/portfolio/levels/deadlock/",
"title": "Deadlock",
"subject": "Half-Life 2: Opposition",
"image": "https://picsum.photos/445/296?random=1",
"alt": "Image 1"
},]
I've tried If statements, assigning booleans for isLast index, spacing and other formatting but nothing works...
Answer
The main issue here was separating my array into a new suggestions array minus the filtered item, which makes forloop.last actually happen. The other way was just ignoring the filtered item, but considering it still part of the array, which is why forloop.last was never true.
I also use {% raw %} tag to escape the JSON brackets for safe measure. I thought this might be causing Jekyll to try and process them as a tag, leading to an error with no actual error output in the --verbose build logs. Although I think the main culprit was the need to create a separate array to loop through.
{% assign suggestions = "" | split: ',' %}
{%- for item in site[page.collection] -%}
{%- unless item.url == page.url -%}
{% assign suggestions = suggestions | push: item %}
{%- endunless -%}
{%- endfor -%}
<script id="suggest-json" type="application/json">
[
{%- for item in suggestions -%}
{% assign images = item.media | where: "type", "image" %}
{% assign image = images.first %}
{% raw %}
{
{% endraw %}
"url": "{{ site.baseurl }}{{ item.url }}",
"title": {{ item.title | jsonify }},
"subject": {{ item.game | jsonify }},
"image": {{ image.thumbnail | jsonify }},
"alt": {{ image.thumbnail_alt | jsonify }}
{% raw %}
}
{% endraw %}
{%- unless forloop.last -%},{%- endunless -%}
{%- endfor -%}
]
</script>
I'm using Full Calendar https://fullcalendar.io/ and have everything working as I want except for one thing. When navigating to the next/previous month I'd like the url bar to update so that it's possible to share a direct link to that month.
Currently at domain.com/events clicking next/prev moves the month but the url is not updated.
Is this possible?
In case it's relevant this is the javascript I'm using
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'dayGridMonth',
headerToolbar: {
start: '',
center: 'prev title next',
end: ''
},
locale: '{{ craft.app.language }}',
showNonCurrentDates: true,
fixedWeekCount: false,
// event display block removes dot
eventDisplay:'block',
eventClassNames: 'has-event',
eventColor: '#de242b',
eventBorderColor: '#fff',
eventTextColor: '#fff',
eventBackgroundColor: '#de242b',
events: [
// add in event stuff here
{% for event in craft.entries.section('events').all() %}
{% set eventEnd %}
{% if event.eventEndDate|length %}
{{ event.eventEndDate|date('Y-m-d')|json_encode|raw }} + 'T23:59:00'
{% else %}
{{ event.eventStartDate|date('Y-m-d')|json_encode|raw }} + 'T23:59:00'
{% endif %}
{% endset %}
{
title: {{ event.title|json_encode|raw }},
start: {{ event.eventStartDate|date('Y-m-d')|json_encode|raw }},
end: {{ eventEnd }},
url: {{ event.url|json_encode|raw }},
textColor: 'white',
backgroundColor:'#de242b',
},
{% endfor %}
]
});
calendar.render();
});
I am getting data from a json file into my datatable.
"columns": [
{% for key, value in columns %}
{
"data": "{{ key }}"},
{% endfor %}
]
Like this I get the following output:
id name slug icon
2 Mitarbeiter members [object Object]
3 Angebote offers [object Object]
4 Produkte products [object Object]
5 Felder fields [object Object]
To recieve the data of the object, I changed my code to this:
"columns": [
{% for key, value in columns %}
{ "data": "{{ key }}.name",
"defaultContent": "{{ key }}"},
{% endfor %}
]
This is working well for the object, but now my other fields do not show the value anymore, the show the label of the column:
id name slug icon
id name slug icon
id name slug anchor
id name slug adjust
id name slug cloud
dump of columns:
array:5 [▼
"id" => ReflectionProperty {#6092 ▶}
"name" => ReflectionProperty {#6094 ▶}
"slug" => ReflectionProperty {#6096 ▶}
"icon" => ReflectionProperty {#6097 ▶}
]
Another approach is this:
"columns": [
{% for key, value in columns %}
{% if key is iterable %}
{"data": "{{ key }}"},
{% else %}
{"data": "{{ key }}.name"},
{% endif %}
{% endfor %}
]
But here I get only the output of the icons row...
The json file is this:
[{"id":2,"name":"Mitarbeiter","icon":{"id":2,"name":"anchor"},"slug":"members"},{"id":3,"name":"Angebote","icon":{"id":1,"name":"adjust"},"slug":"offers"},{"id":4,"name":"Produkte","icon":{"id":1,"name":"adjust"},"slug":"products"},{"id":5,"name":"Felder","icon":{"id":1,"name":"cloud"},"slug":"fields"}]
Finally found a solution:
"columnDefs": [
{
"render": function (data, type, row) {
var type = typeof data;
if(type == "object"){
return data.name;
} else {
return data;
}
},
"targets": "_all"
}
],
"columns": [
{% for key, value in columns %}
{ "data": "{{ key }}"},
{% endfor %}
]
Truy to use: of_type('object')
"columns": [
{% for key, value in columns %}
{
"data": "{% if key is of_type('object') %}{{ key }}.name{% else %}{{ key }}{% endif %}"},
{% endfor %}
{ "data": "id" }
]
I want to set the variable key before using it
"columns": [
{% for key, value in columns %}
{"data": "{{ key }}"},
{% endfor %}
{ "data": "id" }
]
My approach:
"columns": [
{% for key, value in columns %}
{% set result = '{{ key }}' %}
{"data": "{{ result }}"},
{% endfor %}
{ "data": "id" }
]
But it is not working. I get the error message:
Requested unknown parameter '{{ key }}'
{% set result = key %}
From what I see, you want to set the value of result variable, result of key is already set, you just didn't access it correctly.
This does not hide the month and day widgets entirely...
{% block date_widget %}
{% spaceless %}
{% if widget == 'single_text' %}
{{ block('field_widget') }}
{% else %}
<div {{ block('widget_container_attributes') }}>
{{ date_pattern|replace({
'{{ year }}': form_widget(form.year),
'{{ month }}': form_widget(form.month, { 'attr' : { 'style': 'display:none' }}),
'{{ day }}': form_widget(form.day, { 'attr' : { 'style': 'display:none' }}),
})|raw }}
</div>
{% endif %}
{% endspaceless %}
{% endblock date_widget %}
...and this:
'{{ month }}': '',
'{{ day }}': '',
fails during validation.
Any ideas how we can remove day and month widgets from the date form field?
The date type without the month and day parts is just a year type. So, why don't you create one instead of misusing the type meant for dates?
You could use the choice type or create a year type based on it. You could also take a look at the years options of the birthday type and add a similar option to your new type.