Shopify Looping Over JSON Metafield Arrays - json

For some reason, I can't access an array within a JSON metafield.. I've tried the other StackOverflow answers, and I'm using value, etc. but just can't figure it out, here's my metafield:
product.metafields.artist.releases
with a value of:
{
  "releases": [
   { 
"id": 0,
    "releaseName": "lofi 1",
    "coverArt": "",
    "releaseLink": “”
},
 { 
"id": 1,
    "releaseName": " lofi 2",
    "coverArt": "",
    "releaseLink": “”
}
]}
(which formats to: "{\"releases\":[{\"id\":0,\"releaseName\":\"lofi 1\",\"coverArt\":\"\",\"releaseLink\":“”},{\"id\":1,\"releaseName\":\"lofi 2\",\"coverArt\":\"google.com\",\"releaseLink\":“”}]}")
and I'm using this in the product.custom.liquid:
{{ product.metafields.artist.releases.value }}
{% assign releases = product.metafields.artist.releases.value %}
{% for release in releases.releases %}
{{ release.releaseName }}
{% endfor %}
the first one shows up fine, and if I assign it and do {{ releases }} it shows up fine as well so I know the assignment is working, but I can't forloop over it (mind you that the first object in the JSON is also called releases (I've also tried renaming it all to unique names just in case and that didn't help))

For some reason when it is a multidimensional JSON array it acts weird. There is a simple fix for it, just add (-) at the end of your assigned variable:
{%- assign releases = product.metafields.artist.releases.value -%}
{% for release in releases.releases %}
{{ release.releaseName }}
{%- endfor -%}
Hope it solves your problem like it did mine!

Liquid is not going to work on JSON like this. If you want to iterate through an array of JSON objects, use Javascript.

As lov2code points out by adding (-) it trims the output for any unnecessary white space, which enables you to traverse the JSON array.

Related

django template html how to use filter with a context value as a string argument of that filter

i'm try to do smthing like this:
{% for i in list %} <td style="background-color: {{color_rule|get_item:i}}">{{i}}</td> {% endfor %}
where:
def get_item(dictionary, key): return dictionary.get(key)
please help
The dictionary keys are lower case letters but the list are all uppercase - keys are case sensitive so nothing is being returned. Change your list to all lower case or your dict keys to uppercase and it will work.
Referring to the comment with additional context:
color_rules = {
'c':'rgb(87,213,255)',
'a':'rgb(182,83,248)',
'g':'rgb(163,196,60)',
't':'rgb(243, 100, 96)',
},
list = "CAGCCAGACCACAGGCCAGACATGACGTGGAGGCAAGCGGCCACAACGTGGAGGTGGA"
As an aside, you should avoid naming variables with python functions, i.e. list() - also the list isn't actually a list but a string. Something like color_string would be more appropriate.
According to the documentation.
{% for key, i in list.items %}
{{ key }}: {{ i}}
{% endfor %}

jinja2 - create href with variable from loop

I'm try to create a dynamic href for a website
I've tried this:
(where "gruppe" is a list of servers)
{%- for item in groups[gruppe] %}
{% set url = 'https://cmk.abc.local/abc/check_mk/view.py?host=' + {{ hostvars[item]['openstack']['name'] }} + '&site=abc&view_name=host' %}
{{ hostvars[item]['openstack']['name'] }}.abc.local
{% endfor %}
Expected result should be:
https://cmk.abc.local/abc/check_mk/view.py?host=server01&site=abc&view_name=host#
Does anyone have an idea what I'm doing wrong?
It's tough to say without knowing the shape of the data. If you can post what "groups" looks like (as JSON) that would be helpful.
The first thing that stands out to me is "gruppe". Is that supposed to be a key in the groups object or is that supposed to be dynamic?
Try:
{%- for item in groups["gruppe"] %}
...

How to handle json dictionary in Liquid templates?

I am rather new to Liquid templates, but I don't seem to find a way to loop through a dictionary in json and access the different values.
Disclaimer: I am using the Shopify Liquid Preview extension for VSCode.
Input json file:
The input file contains two properties: CustomerId and Transactions, which is the 'dictionary' property, containing a list of KeyValuePairs. I want to loop through the Transactions collection and output the TransactionValue properties.
{
"CustomerId": 13,
"Transactions": {
"1": {
"Id": "1",
"TransactionValue": 1000
},
"2": {
"Id": "2",
"TransactionValue": 207.47
}
}
}
Expected output:
<h1>Customer 13</h1>
<ul>
<li>1000</li>
<li>207.47</li>
</ul>
Current Attempt
I can easily loop the collection, but then it's not clear to me on how I can access the actual properties of the current transaction. None of the following work. When just outputting the variable, it gets printed like this: 1,[object Object]
<ul>
{% for trx in Transactions %}
<li>{{trx}}</li>
<li>{{trx.Key}}</li>
<li>{{trx.Value}}</li>
<li>{{trx.Object}}</li>
{% endfor %}
</ul>
I don't really have control over the input json, so I was hoping to find a good way on making this work as is.
Thank you
In most Liquid flavors it should be possible to reference an object field by name like this:
{{ Transactions["1"].TransactionValue }}
Then it is a matter of getting all known transactionIds from somewhere. If they're not available as an array, then the dirty solution could be to parse raw incoming JSON, e.g. like that:
{% assign transactionIds = Transactions | split: "\"Id\": \"" %}
<ul>
{% for id in transactionIds %}
{% if id[0] != "{" %}
{% assign realId = id | split: "\"" | first %}
<li>
{{ Transactions[realId].TransactionValue }}
</li>
{% endif %}
{% endfor %}
</ul>

Jekyll - Evaluate a string before assignment

I need to capture a string into a variable tag, then use this variable in site.tags.tag. The code is:
{% capture tag %}programming{% endcapture %}
{{ tag }}
{%- assign titles = site.tags.tag | map: "title" -%}
{{ titles }}
This code only prints prints:
programming
But if I replace site.tags.tag with either site.tags.programming or site.tags.'programming' I get the desired output:
programming
title1 title2
Is there a way to evaluate the variable tag before the assignment? After reading a similar question I tried site.tags.{{tag}} but it didn't work.
site.tags[tag] might be what you're looking for.

Using Jekyll, how do you alter an array's contents using a for loop?

Say I have an array thingy.foo = ['abc', 'def'] in my scope.
My goal is to be able to loop over all the items in thingy.foo and apply some conditional logic to it, overwriting the existing item in the array... Something like this:
{% for item in thingy.foo %}
{% assign thingy.foo[forloop.index0] = site.data.lookups[item] | default: item %}
{% endfor %}
What I am doing do the item is a bit irrelevant, the part I'm having issues with is updating the item in the array. The code compiles and runs. Within the loop, I can confirm that the "lookup" part works (if I assign it to t and inspect t then I get a looked up value, but thingy.foo[0] is still the original value).
Is it possible to update/overwrite arrays in Jekyll?
(this is intended for use on GitHub Pages, so I cannot use custom plugins).
It looks like you cannot mutate existing arrays... but you can loop over the initial array and mutate items into a new array, like this:
{% assign newArray = '' | split: '' %}
{% for item in thingy.foo %}
{% assign newItem = site.data.lookups[item] | default: item %}
{% assign newArray = newArray | push: newItem %}
{% endfor %}
The newArray now contains a list of altered items from thingy.foo.