I'm trying to use the json_decode twig filter from Craft to decode an array of entry objects that got encoded in a macro.
In the macro, the array of entry objects gets encoded by json_encode and echoed:
{{ orderedFutureEvents|json_encode }}
This is how the macro value gets set in the template:
{% set events = craft.entries()
.section('eventPost')
.all() %}
{% import "_macros/events.html" as eventsMacro %}
{% set futureEvents %}
{{ eventsMacro.futureEvents(events)|json_decode }}
{% endset %}
When loading the page it's used on, I get a syntax error:
Invalid Argument – yii\base\InvalidArgumentException
Syntax error.
The specific lines that trows the error:
yiisoft/yii2/helpers/BaseJson.php at line 133
yiisoft/yii2/helpers/BaseJson.php at line 107
Compiled template line:
$context["test"] = craft\helpers\Json::decode((isset($context["futureEvents"]) || array_key_exists("futureEvents", $context) ? $context["futureEvents"] : (function () { throw new RuntimeError('Variable "futureEvents" does not exist.', 19, $this->source); })()));
What's causing this error?
Full macro:
{% macro futureEvents(events) %}
{% set today = "now"|date('d/m/Y') %}
{% set now = "now"|date('U') %}
{% set futureEvents = [] %}
{% for event in events %}
{% for block in event.calendar.level(1).all() %}
{% switch block.type.handle %}
{% case 'periodOfDays' %}
{% if block.endDate|date('d/m/Y') > today %}
{% if block.startDate|date('d/m/Y') < today %}
{# Ongoing event #}
{% set futureEvents = futureEvents|merge([{'date': today, 'event': event}]) %}
{% else %}
{# Future event #}
{% set futureEvents = futureEvents|merge([{'date': block.startDate|date('d/m/Y'), 'event': event}]) %}
{% endif %}
{% endif %}
{% case 'specificDates' %}
{% set tempEvent = [] %}
{% set break = false %}
{% set empty = false %}
{% for child in block.children.all() if not break %}
{% if child.dateAndTime|date('U') > now %}
{# Future event #}
{% set tempEvent = [{'date': child.dateAndTime|date('d/m/Y'), 'event': event}] %}
{% set break = true %}
{# Break because event is found #}
{% elseif (child.dateAndTime|date('U') + child.duration*60) > now %}
{# Ongoing event #}
{% set tempEvent = [{'date': today, 'event': event}] %}
{% set break = true %}
{# Break because event is found #}
{% endif %}
{% else %}
{% set empty = true %}
{% endfor %}
{% if tempEvent is same as([]) and empty %}
{# Fallback on default #}
{% elseif tempEvent is not same as([]) %}
{% set futureEvents = futureEvents|merge(tempEvent) %}
{% endif %}
{% endswitch %}
{% else %}
{% if event.dateAndTime|date('U') > now %}
{# Future event #}
{% set futureEvents = futureEvents|merge([{'date': event.dateAndTime|date('d/m/Y'), 'event': event}]) %}
{% elseif (event.dateAndTime|date('U') + event.duration*60) > now %}
{# Ongoing event #}
{% set futureEvents = futureEvents|merge([{'date': today, 'event': event}]) %}
{% endif %}
{% endfor %}
{% endfor %}
{% set orderedFutureEvents = [] %}
{% for key in futureEvents|sort((a, b) => a <=> b)|column('date', 'event')|keys %}
{% set orderedFutureEvents = orderedFutureEvents|merge([futureEvents[key].event]) %}
{% endfor %}
{{ orderedFutureEvents|json_encode|raw }}
{% endmacro %}
orderedFutureEvents
is an array of entries that you JSON encode into a string. Isevents
in your macro the same JSON encodedorderedFutureEvents
that gets passed into the macro? – Brad Bell Oct 26 '20 at 3:13events
parameter is an array of entry objects. The macro filters out specific entries to return a new array of entry objects. I'll update my post to make it a bit more clear. – Joorren Oct 26 '20 at 14:36