In jinja2, I have a loop inside another loop and I want to write a comma if not last loop.
This is what I have so far:
// ksp = "{'a': ['someString', ['someString'], ['a1', 'a2']], 'b': ['someString', ['someString'], ['b1', 'b2', 'b3']]}"
"users": {
{% for kvd in ksp %}
{% set outer_loop = loop %}
{% for kvt in ksp[kvd][2] %}
"{{ kvt }}": {
"username": "{{ ksp[kvd][1][0] }}"
}{% if not outer_loop.last %},{% endif %}{% endfor %}{{ '' }}{% endfor %}
},
This is what I'm getting:
"users": {
"a1": {
"username": "someString"
},
"a2": {
"username": "someString"
},
"b1": {
"username": "someString"
}
"b2": {
"username": "someString"
}
"b3": {
"username": "someString"
}
}
As you can see, it's missing commas in the last three because they belong to the last outer_loop.index and because of that, it's not a valid JSON. How can I solve this?
Working now, it was just a matter of changing the "if" condition to:
{% if not (outer_loop.last and loop.last) %},{% endif %}{% endfor %}{{ '' }}{% endfor %}
Related
I am trying to create a JSON object using a liquid template, but the fields array in my output is not properly formatted. For example, my input is:
{
"queryString": "id:00000000-0000-0000-0000-000000000000",
"fields": [
"linkFilename",
"documenttype",
"description",
"webUrl"
]
}
And my desired output is:
{
"requests": [
{
"entityTypes": [
"listItem"
],
"query": {
"queryString": "id:00000000-0000-0000-0000-000000000000"
},
"region": "EMEA",
"fields": [
"linkFilename",
"documenttype",
"description",
"webUrl"
]
}
]
}
But my current liquid template:
{% capture output %}
{
"requests": [
{
"entityTypes": ["listItem"],
"query": {
"queryString": "{{ queryString }}"
},
"region": "EMEA",
"fields": ["{{ fields }}"]
}
]
}
{% endcapture %}
{{ output }}
results in:
{
"requests": [
{
"entityTypes": [
"listItem"
],
"query": {
"queryString": "id:00000000-0000-0000-0000-000000000000"
},
"region": "EMEA",
"fields": [
"linkFilenamedocumenttypedescriptionwebUrl"
]
}
]
}
How can I separate the elements in the fields array with a comma in the liquid template?"
{% capture fieldList %}
{% for i in input.fields %}
"{{ i }}"
{% if forloop.last != true %},{% endif %}
{% endfor %}
{% endcapture %}
{% capture output %}
{
"requests": [
{
"entityTypes": [
"listItem"
],
"query": {
"queryString": "{{ input.queryString }}"
},
"region": "EMEA",
"fields": [
{{ fieldList }}
]
}
]
}
{% endcapture %}
{{ output }}
I have received a JSON payload for an order / abandon cart in this format.
{
"tokens": {
"locale": "en_GB",
"currency": "EUR",
"entity_id": "36140",
"item[0].type": "straw",
"item[0].row_total_incl_tax": "2000.0000",
"item[0].quantity": "2.0000",
"item[0].name": "Diego",
"item[0].straw_type": "itri",
"item[0].mot": "20",
"item[1].type": "virtual",
"item[1].row_total_incl_tax": "625.0000",
"item[1].quantity": "1.0000",
"item[1].name": "Mixmatch",
"item[2].type": "straw",
"item[2].row_total_incl_tax": "1000.0000",
"item[2].quantity": "1.0000",
"item[2].name": "Diego",
"item[2].straw_type": "abc",
"item[2].mot": "20",
"item[3].type": "straw",
"item[3].row_total_incl_tax": "600.0000",
"item[3].quantity": "1.0000",
"item[3].name": "Pete",
"item[3].straw_type": "itri",
"item[3].mot": "20"
}
}
I can print values like tokens.entity_id - this works successfully.
However, for each of the Items e.g. item[0] I want to pull the item.name to print using Twig and can't seem to make this work.
I have tried several things e.g.
{% set cart = contact.json_field | json_decode %}
{% for tokens in cart %}
Entity : {{tokens.entity_id | raw }} <br>
{% for item in tokens %}
Item Name : {{item.name | raw }} <br>
{% endfor %}
{% endfor %}
I have also tried tokens.item.name, and tokens.item1.name, and tokens.item[1].name but never seems to be able to pull the values for the items.
Any help would be appreciated as I'm new to Twig
Managed to resolve this, by restructuring the json data
<ul>
Item Name : {{tokens.entity_id | raw }}
{% set count = 0 %}
{% for item in tokens.items %}
{% set counter = ( counter | default(0) ) + 1 %}
{% set test = tokens.items.1.type %}
{{counter}}
Item Name : {{tokens.items.1.type | raw }}
Item Name : {{tokens.items.1.row_total_incl_tax | raw }}
{% endfor %}
</ul>
json
"link_order_status": "http://testing.com/en/",
"items": {
"0": {
"type": "straw",
"row_total_incl_tax": "400.0000"
},
"1": {
"type": "testing #1",
"row_total_incl_tax": "300.0000"
},
"2": {
"type": "testing #2",
"row_total_incl_tax": "200.0000"
}
}
I am trying to extract the value of snapshot_policy_schedules.snapshot_schedule_info from the below list:
[
{
'enabled': 'true',
'policy': 'default-DR',
'policy_owner': 'vserver-admin',
'snapshot_policy_schedules': {
'snapshot_schedule_info': [
{
'count': '6',
'prefix': 'hourly',
'schedule': 'hourly',
'snapmirror_label': '-'
},
{
'count': '2',
'prefix': 'daily',
'schedule': 'daily',
'snapmirror_label': 'daily'
},
{
'count': '2',
'prefix': 'weekly',
'schedule': 'weekly',
'snapmirror_label': 'weekly'
}
]
},
'total_schedules': '3',
'vserver_name': 'net'
}
]
However I am getting the error:
fatal: [localhost]: FAILED! => {"changed": false, "msg": "AnsibleUndefinedVariable: 'list object' has no attribute 'snapshot_policy_schedules'"}
This is my code:
{% for schedule in policy.snapshot_policy_schedules.snapshot_schedule_info %}
{% if schedule.schedule == 'weekly' %}
{% set policy_weekly = schedule.count %}
{% endif %}
{% if schedule.schedule == 'daily' %}
{% set policy_daily = schedule.count %}
{% endif %}
{% if schedule.schedule == 'hourly' %}
{% set policy_hourly = schedule.count %}
{% endif %}
{% endfor %}
Q: "'list object' has no attribute 'snapshot_policy_schedules'"
A: The 'list object' i.e. the variable policy is a list. You probably want to address the first element
{% for schedule in policy.0.snapshot_policy_schedules.snapshot_schedule_info %}
For example, simplified JSON
{
"policy": [{
"schedules": {
"info": [
{"count": "6","prefix": "hourly"},
{"count": "2","prefix": "daily"},
{"count": "2","prefix": "weekly"}]
}
}]
}
and simplified Jinja
- debug:
msg: |-
{% for item in policy.0.schedules.info %}
{{ item.count }} {{ item.prefix }}
{% endfor %}
give
msg: |-
6 hourly
2 daily
2 weekly
Another solution to get the first element of a sequence is to use the first filter of Jinja:
{% for schedule in (policy | first).snapshot_policy_schedules.snapshot_schedule_info %}
"artists": {
"href": "https://api.spotify.com/v1/search?query=Hozier&type=artist&offset=0&limit=20",
"items": [
{
"images": [
{
"height": 640,
"url": "https://i.scdn.co/image/2e4114631a20bd71903bc335b88f872afdce9a33",
"width": 640
},
{
"height": 320,
"url": "https://i.scdn.co/image/4d4be818dc98d47b9086ecff8ec4883902781070",
"width": 320
},
{
"height": 160,
"url": "https://i.scdn.co/image/c181b6184e82bd7f8411d97b87e4f1daa1bbbbb8",
"width": 160
}
]
}
]
}
I'm trying to access the value of the url key in the second dict using jinja2, the problem is that every time i run the webpage it gives me a status code 500 and upon closer look in the terminal it gives me a jinja2.exceptions.UndefinedError: list object has no element 1 but that doesn't make sense to me since it prints {{value[1]}} just fine. The issue arises when i try to loop through the keys and values of that dict.
The following is my jinja2 code. if you can point out what i'm doing wrong or what i'm missing here that would be truly appreciated.
{% if q_type == "artist" %}
{% for record in results['artists']['items'] %}
{% for key, value in record.items() %}
{% if key == "images" %}
{% for k, v in value[1].items() %}
{% if k == "url" %}
{{info.append(v) or ""}}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
{% endfor %}
{% endif %}
I've created this autocomplete file, and it works:
{
"scope": "source, text",
"completions":
[
{ "trigger": "load: {% load ... %}", "contents": "{% load ${1:static} %}$0" },
{ "trigger": "call: {% ... %} (call)", "contents": "{% $1 %}$0" },
{ "trigger": "comment: {% comment %}...{% endcomment%}", "contents": "{% comment %}\n\t$0\n{% endcomment %}\n" },
{ "trigger": "lcm: {# ... #} (line comment)", "contents": "{# $0 #}" },
{ "trigger": "if: {% if %}...{% endif %} ", "contents": "{% if $1 %}\n\t$0\n{% endif %}\n" },
{ "trigger": "ife: {% if %}...{% else %}...{% endif %}", "contents": "{% if $1 %}$2{% else %}$3{% endif %}$0" },
{ "trigger": "ife: {% if %}\\n...\\n{% else %}...{% endif %}", "contents": "{% if $1 %}\n\t$0\n{% else %}\n{% endif %}\n" },
{ "trigger": "url: {% url '...' %}", "contents": "{% url '$1' %}$0" },
{ "trigger": "extends: {% extends '...' %}", "contents": "{% extends '${1:base.html}' %}$0" },
{ "trigger": "var: {{ ... }}", "contents": "{{ $1 }}$0" },
{ "trigger": "block: {% block ... %}...{% endblock %}", "contents": "{% block $1 %}$0{% endblock %}" },
{ "trigger": "block: {% block ... %}\\n...\\n{% endblock %}", "contents": "{% block $1 %}\n$0\n{% endblock %}" },
{ "trigger": "for: {% for ... in ... %}...{% endfor %}", "contents": "{% for $1 in $2 %}\n\t$0\n{% endfor %}" }
]
}
However, the popup is only automatically showing up when I try to use it in this file:
When in an HTML, txt, or py file, however (at least those are the three I tested so far), although the snippet expands properly when you hit tab (the trigger key), the popup dialog does not display unless and until you hit the tab key.
How do I get the popup to automatically display in these other types of files?
Open your user preferences and add the text scope (e.g. text or text.html) to the auto_complete_selector setting